我希望提取的文本的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搜索,我将不胜感激
答案 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]
等位置查询应该是最后的选择,因为在它们之前添加某些内容时,它们往往容易破解。您应该仔细检查标记并尝试使用id
或class
等属性进行查询,因为它们比位置标记更可靠地添加特异性。但最后,这一切都归结为相关页面的具体细节。
答案 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)
您尚未明确提及,但如果您的目标table
和td
标记类可靠,那么您可以执行以下操作:
//table[@class="123"]/descendant::td[@class="val"]
你有一半躲避tbody
存在与否的问题。
然而,实际上看到你试图解析推荐XPATH查询的材料是无可替代的......