【问题标题】:LXML XPath expression returns only the first child node, while browser confirms multiple childrenLXML XPath 表达式仅返回第一个子节点,而浏览器确认多个子节点
【发布时间】:2020-07-07 17:37:00
【问题描述】:

我正在尝试使用 Python lxml 库来解析网页。在 Firefox 的开发者视图中,页面树清楚地显示为:

但是,当我在 Python 中运行此查询时:

>>> spellTree.xpath('//span[@id="ctl00_MainContent_DetailedOutput"]/child::node()')
[<Element h1 at 0x445a4b0>]`

它只将h1 元素视为span 的子元素,而不是其他spans 或h1 之后的任何其他节点,即使树清楚地表明它们是子元素。

它确实确定文档中存在其他跨度:

>>> spellTree.xpath('//span[@class="trait"]//child::node()')
[<Element a at 0x445a570>, 'Acid', <Element a at 0x445a5a0>, 'Attack', <Element a at 0x445a600>, 'Cantrip', <Element a at 0x445a5d0>, 'Evocation']

但它没有记录它们是DetailedOutput 跨度的子级。我的 XPath 是错误的,还是错误或异常?

编辑:Python 3.7.3、lxml 4.5.1。

【问题讨论】:

  • 尝试将spellTree.xpath('//span[@id="ctl00_MainContent_DetailedOutput"]/child::node()') 更改为spellTree.xpath('//span[@id="ctl00_MainContent_DetailedOutput"]//child::node()')(注意child::node 之前的两个//)。
  • 这显示了 h1、a、span 和 img,它们是初始 h1 的间接后代(并非全部显示在屏幕截图中)。但是还是没有显示后面的spans。
  • 没有实际的 url 就很难分辨。

标签: python web-scraping lxml


【解决方案1】:

它可能是格式错误的 html。

看起来//span[@id="ctl00_MainContent_DetailedOutput"] 不是//span[@class="trait"] 的孩子;相反,他们看起来像兄弟姐妹。这就是//span[@id="ctl00_MainContent_DetailedOutput"]//child::node() 仅显示 4 个子节点的原因。

这可能是原因:span[@id="ctl00_MainContent_DetailedOutput"] 标签内似乎有一个杂散的&lt;/span&gt;;这可能会导致 html 解析器认为 span[@id="ctl00_MainContent_DetailedOutput"] 已关闭,从而导致将下一个跨度 (//span[@id="ctl00_MainContent_DetailedOutput"]) 视为其兄弟而不是其子。

【讨论】:

  • 看起来像。 spellTree.xpath('//span[@id="ctl00_MainContent_DetailedOutput"]/following-sibling::node()') 工作。想知道为什么与 Firefox 不匹配?
  • @MarkGreen 不清楚;它也可能与 lxml html 解析器如何处理错误有关。不幸的是,lxml 本身远非完美。
猜你喜欢
  • 1970-01-01
  • 2015-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-25
  • 2011-11-21
相关资源
最近更新 更多