2

我希望提取的文本的 xpath 可靠地位于树的深处

...table/tbody/tr[4]/td[2]

具体来说, td[2] 的结构如下

<td class="val">xyz</td>

我正在尝试提取文本“xyz”,但广泛搜索会返回多个结果。例如,以下路径返回 10 个元素。

xpath('//td[@class="val"]')

...虽然特定搜索不返回任何元素。我不确定为什么以下内容不返回任何内容。

xpath('//tbody/tr/td[@class="val"]')

一种解决方案涉及..

table = root.xpath('//table[@class="123"]')

#going down the tree
xyz = table[0][3][1]
print vol.text

但是,我很确定这非常脆弱。如果有人能告诉我如何构建既不脆弱又资源相对便宜的 xpath 搜索,我将不胜感激

4

3 回答 3

2
...table/tbody/tr[4]/td[2]

我猜你是通过像 Firebug 这样的工具找到这个 XPath 的。关于 Firebug(或浏览器中的其他检查工具)之类的工具需要注意的一点是,它们使用浏览器本身生成的 DOM 树,并且浏览器中的大多数(如果不是全部)HTML 解析器会努力使传递的 HTML 有效。这通常需要添加标准规定的各种标签。

<tbody>是这些标签之一。<tr>标记只能作为<thead><tbody><tfoot>标记的子级。不幸的是,根据我的经验,您很少会<table>在实际源代码中看到其中一个标签,但是浏览器会在解析时添加这些必要的标签以使 HTML 有效,因为标准要求这样做

简而言之,<tbody>您的实际来源中可能没有标签。这就是您的 XPath 什么也不返回的原因。

至于生成 XPath 查询,这高度依赖于特定的页面/xml。一般来说,位置查询td[4]应该是最后的手段,因为当在它们之前添加一些东西时,它们往往很容易中断。您应该仔细检查标记并尝试提出使用属性的查询,id或者class因为它们比位置属性更可靠地添加了特异性。但最终,这一切都归结为相关页面的细节。

于 2012-05-02T21:17:39.750 回答
2

您没有明确提到它,但是如果您的目标tabletd标记类是可靠的,那么您可以执行以下操作:

//table[@class="123"]/descendant::td[@class="val"]

你一半回避了tbody存在与否的问题。

但是,没有什么可以替代实际查看您尝试解析的材料以推荐 XPATH 查询...

于 2012-05-02T22:07:52.360 回答
1

这似乎工作

from lxml import etree

doc = etree.HTML('<html><body><table><tbody><tr><td>bad</td><td class="val">xyz</td></tr></tbody></table></body></html>')
print doc.xpath('//tbody/tr/td[@class="val"]')[0].text

输出:

xyz

那么你的问题是什么?

于 2012-05-02T18:09:33.433 回答