我想用python3和LXML提供的HTML Parser提取一些HTML元素。
考虑此html:
<!DOCTYPE html>
<html>
<body>
<span class="foo">
<span class="bar">bar</span>
foo
</span>
</body>
</html>
考虑此程序:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from lxml import html
tree = html.fromstring('html from above')
bars = tree.xpath("//span[@class='bar']")
print(bars)
print(html.tostring(bars[0], encoding="unicode"))
在浏览器中,查询选择器" span.bar"仅选择跨度元素。这就是我想要的。但是,以上程序产生:
[<Element span at 0x7f5dd89a4048>]
<span class="bar">bar</span>foo
看来我的XPATH实际上并不像查询选择器一样行为,并且在跨度元素旁边拾取了同级文本节点。如何调整XPath仅选择条元素,而不是文本" foo"?
请注意,lxml
中的XML树模型(以及标准模块xml.etree
中(具有tail
的概念。因此, ag.a following-sibling
of 元素的 ag.a 将作为该元素的 tail
存储。因此,您的XPath正确返回span
元素,但是根据树模型,它具有tail
,该元素包含文本" foo"。
作为解决方法,假设您不想进一步使用树模型,只需在打印之前清除tail
:
>>> bars[0].tail = ''
>>> print(html.tostring(bars[0], encoding="unicode"))
<span class="bar">bar</span>