为什么我的XPath查询(刮取HTML表)只能在Firebug中工作,但不是我正在开发的应用程序?

前端之家收集整理的这篇文章主要介绍了为什么我的XPath查询(刮取HTML表)只能在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-souphtmltidy这样的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]

猜你在找的HTML相关文章