如何用html5lib解析HTML,并使用XPath查询解析后的HTML?
我正在尝试使用html5lib来解析一个网页,把它变成可以用xpath查询的格式。可是html5lib几乎没有文档,我花了太多时间在解决这个问题上。我的最终目标是提取一个表格的第二行:
<html>
<table>
<tr><td>Header</td></tr>
<tr><td>Want This</td></tr>
</table>
</html>
那么我们来试试:
>>> doc = html5lib.parse('<html><table><tr><td>Header</td></tr><tr><td>Want This</td> </tr></table></html>', treebuilder='lxml')
>>> doc
<lxml.etree._ElementTree object at 0x1a1c290>
看起来不错,我们再看看还有什么:
>>> root = doc.getroot()
>>> print(lxml.etree.tostring(root))
<html:html xmlns:html="http://www.w3.org/1999/xhtml"><html:head/><html:body><html:table><html:tbody><html:tr><html:td>Header</html:td></html:tr><html:tr><html:td>Want This</html:td></html:tr></html:tbody></html:table></html:body></html:html>
哈哈,什么情况?
说真的。我原本打算用一些xpath来获取我想要的数据,但这似乎不太管用。那么我该怎么办呢?我愿意尝试不同的库和方法。
7 个回答
4
我总是建议大家试试 lxml
这个库。它非常快,而且功能很多。
如果你需要的话,它还支持 html5lib 解析器:html5parser
>>> from lxml.html import fromstring, tostring
>>> html = """
... <html>
... <table>
... <tr><td>Header</td></tr>
... <tr><td>Want This</td></tr>
... </table>
... </html>
... """
>>> doc = fromstring(html)
>>> tr = doc.cssselect('table tr')[1]
>>> print tostring(tr)
<tr><td>Want This</td></tr>
19
你想用的是 namespaceHTMLElements
这个参数,出于某种原因,它默认是设置为 True 的。
doc = html5lib.parse('''<html>
<table>
<tr><td>Header</td></tr>
<tr><td>Want This</td></tr>
</table>
</html>
''', treebuilder='lxml', namespaceHTMLElements=False)
print lxml.html.tostring(doc)
不过,使用 lxml.html 可能还是更简单一些。
26
我觉得缺少文档是一个很好的理由去避免使用某个库,不管它有多酷炫。你真的一定要用html5lib吗?你有没有看看lxml.html这个库?
这里有一个用lxml实现这个功能的方法:
from lxml import html
tree = html.fromstring(text)
[td.text for td in tree.xpath("//td")]
结果:
['Header', 'Want This']