【问题标题】:Correct Xpath for element正确的元素 Xpath
【发布时间】:2016-01-05 13:36:25
【问题描述】:

我正在尝试从this page 中抓取一些数据。

我在 python 中使用 requests 和 lxml 来做到这一点。 具体来说,我想要检测到的主题的 id。

我为他们编写了以下 Xpath:

'//detectedTopic//@id'

这没有返回任何内容。

而以下工作没有任何问题:

'//@id'

Chrome 中的开发者工具显示第一个 Xpath 确实指向了正确的节点。

那有什么问题呢?

【问题讨论】:

  • 你能试试下面的2个例子吗? //detectedTopic/@id 或 //detectedTopic

标签: python xpath lxml


【解决方案1】:

如果你使用lxml.html来解析内容,那么HTMLParser会将HTML is case-insensitive之后的所有标签变成小写:

import requests
url = 'http://wikipedia-miner.cms.waikato.ac.nz/services/wikify?source=At%20around%20the%20size%20of%20a%20domestic%20chicken,%20kiwi%20are%20by%20far%20the%20smallest%20living%20ratites%20and%20lay%20the%20largest%20egg%20in%20relation%20to%20their%20body%20size%20of%20any%20species%20of%20bird%20in%20the%20world'
r = requests.get(url)
content = r.content

import lxml.html as LH
html_root = LH.fromstring(content)
print(LH.tostring(html_root))

产量

...
   <detectedtopics>
      <detectedtopic id="17362" title="Kiwi" weight="0.8601778098224363"></detectedtopic>
      <detectedtopic id="21780446" title="Species" weight="0.6213590253455182"></detectedtopic>
      <detectedtopic id="160220" title="Ratite" weight="0.5533763404831633"></detectedtopic>
      <detectedtopic id="37402" title="Chicken" weight="0.528161911497278"></detectedtopic>
   </detectedtopics>

但是如果你使用lxml.etree将内容解析为XML,那么大小写不变:

import lxml.etree as ET
xml_root = ET.fromstring(content)
print(ET.tostring(xml_root))

产量

...
   <detectedTopics>
      <detectedTopic id="17362" title="Kiwi" weight="0.8601778098224363"/>
      <detectedTopic id="21780446" title="Species" weight="0.6213590253455182"/>
      <detectedTopic id="160220" title="Ratite" weight="0.5533763404831633"/>
      <detectedTopic id="37402" title="Chicken" weight="0.528161911497278"/>
   </detectedTopics>

内容看起来像 XML 而不是 HTML,所以你应该使用:

print(xml_root.xpath('//detectedTopic/@id'))
['17362', '21780446', '160220', '37402']

如果内容被解析为 HTML,那么 XPath 需要小写:

print(html_root.xpath('//detectedtopic/@id'))
['17362', '21780446', '160220', '37402']

【讨论】:

  • 很好的答案!我不知道lxml.html 使标签小写,因为我习惯使用lxml.etree 进行xml 解析。
【解决方案2】:

您可以通过以下方式获取 id:

'//detectedTopic/@id'

您还可以获取标签并提取所需的属性。示例:

for tag in tr.xpath('//detectedTopic'):
    print tag.attrib.get('id')
    print tag.attrib.get('title')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-15
    • 2013-10-19
    • 2019-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多