我正在开发一个应用程序,需要使用其中的表解析一个网站。由于派生用于抓取网页的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],它可以再次工作。
怎么了?
解决方法
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 atbody
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]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。