当前位置: 首页 > 面试题库 >

为什么此xpath在python中使用lxml失败?

简烨烁
2023-03-14
问题内容

这是我尝试从中获取数据的示例网页。
http://www.makospearguns.com/product-p/mcffgb.htm

xpath取自chrome开发工具,firefox中的firepath也能够找到它,但是使用lxml时,它只会为“ text”返回一个空列表。

from lxml import html
import requests

site_url = 'http://www.makospearguns.com/product-p/mcffgb.htm'
xpath = '//*[@id="v65-product-parent"]/tbody/tr[2]/td[2]/table[1]/tbody/tr/td/table/tbody/tr[2]/td[2]/table/tbody/tr[1]/td[1]/div/table/tbody/tr/td/font/div/b/span/text()'

page = requests.get(site_url)
tree = html.fromstring(page.text) 
text = tree.xpath(xpath)

使用以下命令打印树文本

print(tree.text_content().encode('utf-8'))

显示数据在那里,但是xpath似乎无法找到它。我有什么想念的吗?我尝试使用lxml和从chrome开发工具中获取的xpath可以正常工作的大多数其他站点,但是我发现其中的一些站点为空。


问题答案:

浏览器经常更改为其提供的HTML,以使其“有效”。例如,如果您为浏览器提供服务,则此无效的HTML:

<table>
  <p>bad paragraph</p>
  <tr><td>Note that cells and rows can be unclosed (and valid) in HTML
</table>

要呈现它,浏览器会很有帮助,并尝试使其成为有效的HTML,并将其转换为:

<p>bad paragraph</p>
<table>
  <tbody>
    <tr>
      <td>Note that cells and rows can be unclosed (and valid) in HTML</td>
    </tr>
  </tbody>
</table>

由于<p>aragraph不能位于<table>s之内,因此更改了上述内容,<tbody>因此建议这样做。应用于源的更改可能因浏览器而异。有些会将无效元素放在表格之前,有些放在表格之后,有些放在内部单元格中,等等。

2. Xpath不是固定的,它们可以灵活地指向元素。

使用此“固定” HTML:

<p>bad paragraph</p>
<table>
  <tbody>
    <tr>
      <td>Note that cells and rows can be unclosed (and valid) in HTML</td>
    </tr>
  </tbody>
</table>

如果我们尝试定位<td>单元格的文本,则以下所有内容将为您提供大致正确的信息:

//td
//tr/td
//tbody/tr/td
/table/tbody/tr/td
/table//*/text()

而这样的例子不胜枚举…

但是,一般而言,浏览器会为您提供最精确(且最不灵活)的XPath,它列出了DOM中的每个元素。在这种情况下:

/table[0]/tbody[0]/tr[0]/td[0]/text()

3.结论:给浏览器指定的Xpath通常无济于事

这就是为什么开发人员工具生成的XPath在尝试使用原始HTML时会经常为您提供错误的Xpath的原因。

该解决方案始终引用原始HTML,并使用灵活但精确的XPath。

检查持有价格的实际HTML:

<table border="0" cellspacing="0" cellpadding="0">
    <tr>
        <td>
            <font class="pricecolor colors_productprice">
                <div class="product_productprice">
                    <b>
                        <font class="text colors_text">Price:</font>
                        <span itemprop="price">$149.95</span>
                    </b>
                </div>
            </font>
            <br/>
            <input type="image" src="/v/vspfiles/templates/MAKO/images/buttons/btn_updateprice.gif" name="btnupdateprice" alt="Update Price" border="0"/>
        </td>
    </tr>
</table>

如果您想要价格,实际上只有一个地方可以看!

//span[@itemprop="price"]/text()

这将返回:

$149.95


 类似资料:
  • 下面是一个我试图从中获取数据的示例网页。http://www.makospearguns.com/product-p/mcffgb.htm xpath取自chrome开发工具,firefox中的firepath也能找到它,但使用lxml它只返回一个空的“文本”列表。 使用 显示数据在那里,但xpath似乎无法找到它。我有什么遗漏吗?我尝试过的大多数其他站点使用lxml和chromedev工具中的x

  • 所以我有这个代码,它应该得到亚马逊上任何商品的价格。然而,我得到的不是价格,而是一个空清单。 这以前对我有用。我将感谢任何帮助。提前感谢。

  • 问题内容: 我正在尝试从网页中打印/保存特定元素的HTML。 我已经从萤火虫中检索了所请求元素的XPath。 我只希望将该元素保存到文件中。我似乎没有成功。 (尝试在XPath的结尾加上和不结尾) 我将不胜感激,或者有以往的经验。 10x,大卫 问题答案: 您的XPath显然太长了,为什么不试试较短的XPath看看它们是否匹配。一个问题可能是“ tbody”,浏览器会在DOM中自动创建“ tbod

  • 问题内容: 我正在针对以下测试文档进行测试: 如果使用lxml.html解析文档,则可以使用xpath获得IMG: 但是,如果我将文档解析为XML并尝试获取IMG标签,则会得到空结果: 我可以直接导航到该元素: 但这当然无助于我处理任意文档。我还希望能够查询etree以获得直接识别该元素的xpath表达式,从技术上讲,我可以这样做: 但是,同样,该xpath显然对解析任意文档没有用。 显然,我在这

  • 我刚开始在 futurelearn.com 学习编程。 我有一个位图和一个球。任务是编码x方向的边界。 工作代码如下所示: 但我有一个逻辑问题。我想知道为什么我不能用“==”代替“ 这是了解的视频。它应该包含所有可能缺少的信息。 https://www.futurelearn.com/courses/begin-programming/7/steps/42942

  • 问题内容: 有一件我不理解的事情。 为什么这样 产生此错误: 问题答案: 发生这种情况是因为该模块没有名为的任何属性。该属性仅在您定义时定义。 子模块不会在您刚导入时自动导入;您需要显式导入它们。对于大多数软件包来说,情况相同,尽管软件包可以根据需要选择导入自己的子模块。(例如,如果包括一份声明, 然后 将子模块会随时导入进口。)