Skip to main content
 首页 » 编程设计

python之XPath 查询(例如 "//th/a")返回不在当前元素下的结果

2025年05月04日15sxdcgaq8080

我有以下脚本:

from lxml import etree 
 
sample_html = ''' 
<body><div><table><tbody> 
<tr> 
  <th><a href="xxx">AAA</a></th> 
  <td data-xxx="AAA-1234"></td> 
  <td data-xxx="AAA-5678"></td> 
</tr> 
<tr> 
  <th><a href="xxx">BBB</a></th> 
  <td data-xxx="BBB-1234"></td> 
  <td data-xxx="BBB-5678"></td> 
</tr> 
</tbody></table></div></body> 
''' 
 
def parse_tree(tree): 
    print '============================> Parsing tree' 
    rows = tree.xpath('//body/div/table/tbody/tr') 
    for row in rows: 
        As = row.xpath('//th/a') 
        for a in As: 
            print a.text 
        tds = row.xpath('//td') 
        for td in tds: 
            print td.attrib['data-xxx'] 
    print 
 
 
body = sample_html 
tree = etree.HTML(body) 
parse_tree(tree) 

这给了我输出:

============================> Parsing tree 
AAA 
BBB 
AAA-1234 
AAA-5678 
BBB-1234 
BBB-5678 
AAA 
BBB 
AAA-1234 
AAA-5678 
BBB-1234 
BBB-5678 

但我期待:

============================> Parsing tree 
AAA 
AAA-1234 
AAA-5678 
BBB 
BBB-1234 
BBB-5678 

也就是说,我期望在 for row in rows 循环中我将只能访问一行。相反,xpath 似乎以某种方式处理整个表。我显然不明白发生了什么。

有人可以阐明 xpath 是如何处理行的,以及它为什么在循环中访问整个表吗?我怎样才能更正我的脚本?

请您参考如下方法:

您的锚定是错误的。而不是:

for row in rows: 
    As = row.xpath('//th/a') 

...使用前导 . 来引用当前元素在树中的位置:

for row in rows: 
    As = row.xpath('.//th/a') 

.// 告诉查询它是相对于树中当前位置的,而领先的 // 明确地从根开始运行递归搜索。


顺便问一下——为什么您的搜索是递归的?您可以将 // 更改为 / 并获得显着的效率。