【问题标题】:Python lxml XPath with deep nesting with specific search具有特定搜索的深度嵌套的 Python lxml XPath
【发布时间】:2012-05-02 17:43:46
【问题描述】:

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

【问题讨论】:

  • 你可以粘贴一些有效的 xml 来测试,而不是给出 `...table/tbody/...'
  • 请提供一个示例 XML 文档。如果超过 10 行,您可以将其上传到 pastebin.comgist
  • 或者您可以修剪 xml 文档,在 python 代码中使用它并粘贴显示问题的示例 python 代码,我想复制粘贴并运行您的代码并查看问题,例如类似于我的回答

标签: python xpath lxml


【解决方案1】:

你没有明确提到它,但如果你的目标 tabletd 标签类是可靠的,那么你可以这样做:

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

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

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

【讨论】:

    【解决方案2】:
    ...table/tbody/tr[4]/td[2]
    

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

    &lt;tbody&gt; 是这些标签之一。 &lt;tr&gt; tags are only allowed as a child of &lt;thead&gt;, &lt;tbody&gt; or &lt;tfoot&gt; tags. 不幸的是,根据我的经验,您很少会在实际源代码中的 &lt;table&gt; 中看到这些标签之一,但浏览器会在解析时添加这些必要的标签,以使 HTML 自 standard requires to do so 起有效。

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

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

    【讨论】:

    • 您可以稍微强调一下您的观点:源代码中没有tbody
    【解决方案3】:

    这似乎有效

    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
    

    那么你的问题是什么?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-21
      • 2012-02-25
      • 2018-04-13
      • 2017-09-07
      • 1970-01-01
      • 2019-03-20
      • 2021-04-20
      相关资源
      最近更新 更多