Python lxml XPath,具有深度嵌套和特定搜索功能

时间:2012-05-02 17:43:46

标签: python xpath lxml

我希望提取的文本的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搜索,我将不胜感激

3 个答案:

答案 0 :(得分:2)

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

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

<tbody>是其中一个标记。 <tr> tags are only allowed as a child of <thead>, <tbody> or <tfoot> tags.遗憾的是,根据我的经验,您很少会在实际来源的<table>内看到其中一个标记,但浏览器会在解析时添加这些必要的标记,以使HTML有效{{3} }。

要简短地讲述这个故事,您的实际来源中可能没有<tbody>标记。这就是你的XPath什么都不返回的原因。

至于生成XPath查询,这在很大程度上取决于特定的page / xml。一般来说,td[4]等位置查询应该是最后的选择,因为在它们之前添加某些内容时,它们往往容易破解。您应该仔细检查标记并尝试使用idclass等属性进行查询,因为它们比位置标记更可靠地添加特异性。但最后,这一切都归结为相关页面的具体细节。

答案 1 :(得分: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

那你的问题是什么?

答案 2 :(得分:0)

您尚未明确提及,但如果您的目标tabletd标记类可靠,那么您可以执行以下操作:

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

你有一半躲避tbody存在与否的问题。

然而,实际上看到你试图解析推荐XPATH查询的材料是无可替代的......