.xpath中的lxml错误?
通过python的lxml教程中的xpath之后,我发现很难理解2个看起来像是bug的行为。首先,即使我的xpath表达式明确选择了一个元素,lxml似乎也会返回一个列表,其次.xpath似乎返回元素的父元素,而不是由直接xpath搜索表达式选择的元素本身。.xpath中的lxml错误?
我对XPath的理解是否全错或者lxml确实有错误?
复制我谈论行为的脚本:
from lxml.html.soupparser import fromstring
doc = fromstring("""
<html>
<head></head>
<body>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</body>
</html>
""")
print doc.xpath("//html")
#[<Element html at 1f385e0>]
#(This makes sense - return a list of all possible matches for html)
print doc.xpath("//html[1]")
#[<Element html at 1f385e0>]
#(This doesn't make sense - why do I get a list when there
#can clearly only be 1 element returned?)
print doc.xpath("body")
#[<Element body at 1d003e8>]
#(This doesn't make sense - according to
#http://www.w3schools.com/xpath/xpath_syntax.asp if I use a tag name
#without any leading/I should get the *child* nodes of the named
#node, which in this case would mean I get a list of
#p tags [<Element p at ...>, <Element p at ...>]
所有p标签应该是doc.findall(".//p")
按照指南,表达nodename
选择所有子节点命名节点的。 因此,要仅使用节点名(无尾/),必须选择一个命名节点(选择父节点作为命名节点,使用点)。
这是因为doc
的上下文节点是'html'
节点。当您使用doc.xpath('body')
时,请选择'html'
的子元素'body'
。这符合XPath 1.0 standard
的行为不同。值得一提的是,'doc.xpath()'总是返回一个列表应该。它简化了使用'.xpath()'的代码。通常总是返回确认相同协议的对象(在这种情况下是一系列元素)是一个好主意。 – jfs 2012-03-19 04:37:46
事实上,doc.xpath("//html[1]")
可以返回不止一个节点,并在您的示例中输入不同的文档。该路径选择匹配// html的第一个兄弟。如果有匹配的非同胞元素,它将选择每个元素的第一个兄弟元素。
XPath:(//html)[1]
强制执行不同的评估顺序。它选择文档中的所有匹配元素,然后选择第一个。
但是,在任何情况下,总是返回一个列表是一个更好的API设计。否则,在处理列表之前,代码总是必须测试单个值或无值。
我的问题不是我无法弄清楚如何使用lxml来选择所有的p标签。我的问题是找出为什么lxml没有错误,因为它的行为与我期望的基于XPath教程 – Trindaz 2012-03-19 03:02:53