lxml HtmlElement xpath解析了它应该能够做的事情

时间:2016-08-03 18:33:05

标签: python xpath lxml

尝试解析HTML,我无法遍历所有li元素:

from lxml import html

page="<ul><li>one</li><li>two</li></ul>"
tree = html.fromstring(page)

for item in tree.xpath("//li"):
  print(html.tostring(item))
  print(item.xpath("//li/text()"))

我期待这个输出:

b'<li>one</li>'
['one']
b'<li>two</li>'
['two']

但我明白了:

b'<li>one</li>'
['one', 'two']
b'<li>two</li>'
['one', 'two']

xpath如何在两个迭代步骤中从li获取item元素'文本?

我可以使用计数器作为索引来解决这个问题,但我想了解发生了什么。

2 个答案:

答案 0 :(得分:1)

item.xpath("//li/text()")将搜索整个树中的所有li元素。由于您需要当前节点的文本,因此您只需获取text()item.xpath("text()")

或者,更好的是,只需获取text content

for item in tree.xpath("//li"):
  print(html.tostring(item))
  print(item.text_content())

答案 1 :(得分:1)

来自Lxml html xpath context

  

XPath表达式//input将匹配文档中任何位置的所有输入元素,而.//input将匹配所有内部当前上下文。

解决方案是使用:

from lxml import html

page="<ul><li>one</li><li>two</li></ul>"
tree = html.fromstring(page)

for item in tree.xpath("//li"):
  print(html.tostring(item))
  print(item.xpath(".//text()")) #only changed line

.之前添加//会阻止匹配整个文档,因为您已经在li/标记的“内部”,因此需要删除li

输出结果为:

b'<li>one</li>'
['one']
b'<li>two</li>'
['two']