使用lxml.html解析HTML时,相当于InnerHTML

som*_*off 24 python parsing lxml

我正在使用lxml.html编写一个脚本来解析网页.我在我的时间里做了很多BeautifulSoup,但由于它的速度,我现在正在尝试lxml.

我想知道库中最明智的方法是做相当于Javascript的InnerHtml - 即检索或设置标签的完整内容.

<body>
<h1>A title</h1>
<p>Some text</p>
</body>
Run Code Online (Sandbox Code Playgroud)

因此InnerHtml是:

<h1>A title</h1>
<p>Some text</p>
Run Code Online (Sandbox Code Playgroud)

我可以使用黑客(转换为字符串/正则表达式等)来做到这一点,但我假设有一个正确的方法来使用由于不熟悉我缺少的库.谢谢你的帮助.

编辑:感谢pobk如此快速有效地向我展示了这方面的方法.对于任何尝试相同的人,这是我最终得到的:

from lxml import html
from cStringIO import StringIO
t = html.parse(StringIO(
"""<body>
<h1>A title</h1>
<p>Some text</p>
Untagged text
<p>
Unclosed p tag
</body>"""))
root = t.getroot()
body = root.body
print (element.text or '') + ''.join([html.tostring(child) for child in body.iterdescendants()])
Run Code Online (Sandbox Code Playgroud)

请注意,lxml.html解析器将修复未关闭的标记,因此请注意这是否存在问题.

lor*_*mus 15

很抱歉再次提出这个问题,但我一直在寻找解决方案,而你的问题包含一个错误:

<body>This text is ignored
<h1>Title</h1><p>Some text</p></body>
Run Code Online (Sandbox Code Playgroud)

直接位于根元素下的文本将被忽略.我最终这样做了:

(body.text or '') +\
''.join([html.tostring(child) for child in body.iterchildren()])
Run Code Online (Sandbox Code Playgroud)


pob*_*obk 10

您可以使用根节点的getchildren()或iterdescendants()方法获取ElementTree节点的子节点:

>>> from lxml import etree
>>> from cStringIO import StringIO
>>> t = etree.parse(StringIO("""<body>
... <h1>A title</h1>
... <p>Some text</p>
... </body>"""))
>>> root = t.getroot()
>>> for child in root.iterdescendants(),:
...  print etree.tostring(child)
...
<h1>A title</h1>

<p>Some text</p>
Run Code Online (Sandbox Code Playgroud)

这可以简化如下:

print ''.join([etree.tostring(child) for child in root.iterdescendants()])
Run Code Online (Sandbox Code Playgroud)

  • 请注意,无论您使用的是"iterchildren"还是"iterdescendants",这两种解决方案都是不正确的,并且会完全忽略父元素包含的文本节点.请参阅http://stackoverflow.com/questions/4624062/get-all-text-inside-a-tag-in-lxml以获得更好的答案. (13认同)
  • 请注意,您将要调用.iterchildren()而不是.iterdescendants() - 后者将导致严重的内容重复,因为.tostring()将自行下降.例如,请参阅"两个"和"四个"节点的重复:https://gist.github.com/1290412 (7认同)