加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 资源网站 > 资源 > 正文

为什么我的XPath查询(刮取HTML表)只能在Firebug中工作,但不是我

发布时间:2020-12-14 21:49:07 所属栏目:资源 来源:网络整理
导读:这是为了提供一个规范的问答(AA),所有类似的(但是太多的具体问题是一个密切的目标候选人)每周弹出一次或两次。 我正在开发一个应用程序,需要使用其中的表解析一个网站。由于派生用于抓取网页的XPath表达式是无聊且容易出错的工作,所以我想使用Firebug(或
这是为了提供一个规范的问答(A&A),所有类似的(但是太多的具体问题是一个密切的目标候选人)每周弹出一次或两次。

我正在开发一个应用程序,需要使用其中的表解析一个网站。由于派生用于抓取网页的XPath表达式是无聊且容易出错的工作,所以我想使用Firebug(或其他浏览器中的类似工具)的XPath提取器功能。

示例输入如下所示:

<!-- snip -->
<table id="example">
  <tr>
    <th>Example Cell</th>
    <th>Another one</th>
  </tr>
  <tr>
    <td>foobar</td>
    <td>42</td>
  </tr>
</table>
<!-- snip -->

我想提取第一个数据单元格(“foobar”)。 Firebug提出XPath表达式

//table[@id="example"]/tbody/tr[2]/td[1]

在任何XPath测试插件中都可以正常工作,但不是我自己的应用程序(没有找到结果)。如果我将查询裁减到// [@id],它可以再次工作。

怎么了?

解决方法

问题:DOM需要< tbody />标签

Firebug,Chrome的开发者工具,JavaScript中的XPath功能和其他功能在DOM上工作,而不是基本的HTML源代码。

HTML的DOM要求脚本标题(< aad />,< tfoot />)中不包含的所有表行都包含在表体标签< tbody />中。因此,如果浏览器在解析(X)HTML时丢失,则添加此标签。例如,Microsoft’s DOM documentation说

The tbody element is exposed for all tables,even if the table does not explicitly define a tbody element.

有一个in-depth explanation in another answer on stackoverflow。

另一方面,HTML does not necessarily require that tag to be used:

The TBODY start tag is always required except when the table contains only one table body and no table head or foot sections.

大多数XPath处理器在原始XML上工作

排除JavaScript,大多数XPath处理器可以处理原始XML,而不是DOM,因此不会添加< tbody />标签。另外像tag-soup和htmltidy这样的HTML解析器库只输出XHTML,而不是“DOM-HTML”。

这是Stackoverflow for PHP,Ruby,Python,Java,C#,Google Docs(Spreadsheets)等等的一个常见问题。 Selenium在浏览器中运行,并在DOM上运行 – 因此它不受影响!

重现问题

比较Firebug(或Chrome的开发工具)所显示的源代码,通过右键单击并选择“显示页面源”(或浏览器中的任何内容) – 或使用curl http://your.example .org在命令行。较后者可能不会包含任何< tbody />元素(它们很少使用),Firebug将始终显示它们。

解决方案1:删除/ tbody轴步

检查你卡住的表是否真的不包含< tbody />元素(见最后一段)。如果是这样,你可能有另一种问题。

现在删除/ tbody轴步骤,所以您的查询将看起来像

//table[@id="example"]/tr[2]/td[1]

解决方案2:跳过< tbody />标签

这是一个相当脏的解决方案,可能会为嵌套表失败(可以跳转到内表)。在极少数情况下,我只会建议这样做。

将/ tbody轴步骤替换为后代或自身步骤:

//table[@id="example"]//tr[2]/td[1]

解决方案3:允许输入有和没有< tbody />标签

如果您不提前确定您的表,或者在“HTML源”和DOM上下文中使用查询,并且不希望/不能使用解决方案2中的黑客,提供替代查询(对于XPath 1.0)或使用“可选”轴步骤(XPath 2.0及更高版本)。

> XPath 1.0:// table [@ id =“example”] / tr [2] / td [1] | //表[@ ID = “例如”] / tbody的/ TR [2] / TD [1]> XPath 2.0:// table [@ id =“example”] /(tbody,。)/ tr [2] / td [1]

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读