0

次のコードがあります。

soup = BeautifulSoup(text)
for elem in soup.find_all('span', 'finereader'):
    elem.replace_with(elem.string or '')

BS が生成するインデントを利用できないため、lxml を使用したいと思います。lxmlを使用した同等のコードはありますか? または、BS のインデントをどのように省略できますか?

助けてくれてありがとう:)

編集:BSは次のような出力を生成します:

<html>
 <body>
  <table border="0" cellpadding="0" cellspacing="0" class="main" frame="box" rules="all" style="table-layout:fixed; width:324.72pt; height:518.64pt;">
   <tr class="row">
    <td class="cell" style=" width:0.00pt; height:0.00pt;" valign="top">
    </td>
    <td class="cell" style=" width:169.44pt; height:0.00pt;" valign="top">
    </td>

しかし、次のような出力が必要です。

<html>
<body>
<table border="0" cellpadding="0" cellspacing="0" class="main" frame="box" rules="all" style="table-layout:fixed; width:324.72pt; height:518.64pt;">
<tr class="row">
<td class="cell" style=" width:0.00pt; height:0.00pt;" valign="top">
</td>
<td class="cell" style=" width:169.44pt; height:0.00pt;" valign="top">
</td>

編集:現時点では、私のコード全体は次のようになります。

output = codecs.open("test.html", "a", "utf-8")

def myfunct():
    for i in range(1, 11):

        root = lxml.html.parse('http://xyz.xy'+str(nr)+'?action=source').getroot()

        for elem in root.xpath("//span[@class='finereader']"):
                text = (elem.text or "") + (elem.tail or "")
            if elem.getprevious(): # If there's a previous node
                previous = elem.getprevious()
                previous.tail = (previous.tail or "") + text # append to its tail
            else:
                 parent = elem.getparent() # Otherwise use the parent
                 parent.text = (parent.text or "") + text # and append to its text
            elem.getparent().remove(elem)

        for empty in root.xpath('//*[self::b or self::i][not(node())]'):
            empty.getparent().remove(empty)

        tables = root.cssselect('table.main') #root.xpath('//table[@class="main" and not(ancestor::table[@class="main"])]') #
        tables = root.xpath('//table[@class="main" and not(ancestor::table[@class="main"])]')

        txt = []

        txt += ([lxml.html.tostring(t, method="html", encoding="utf-8") for t in tables])

        text = "\n".join(re.sub(r'\[:[\/]?T.*?:\]', '', el) for el in txt) #.splitlines())

        output.write(text.decode("utf-8"))
4

1 に答える 1

0

解析するには、 を作成しlxml.etree.HTMLParserて使用しますlxml.etree.fromstring:

import lxml.etree

parser = lxml.etree.HTMLParser()
html = lxml.etree.fromstring(text, parser)

xpath を使用して、必要なものを選択できるようになりました。

for elem in html.xpath("//span[@class='finereader']"):

次に、lxml ではテキスト ノードを追加できず、代わりにノードのコンテンツを処理textするtailため、ノードを文字列に置き換える魔法を実行する必要があります。

    text = (elem.text or "") + (elem.tail or "")
    if elem.getprevious() is not None: # If there's a previous node
        previous = elem.getprevious()
        previous.tail = (previous.tail or "") + text # append to its tail
    else:
        parent = elem.getparent() # Otherwise use the parent
        parent.text = (parent.text or "") + text # and append to its text
    elem.getparent().remove(elem)

次に、 を使用lxml.etree.tostring(html)してテキストを取り戻すことができます。

于 2013-09-02T01:00:48.433 に答える