为什么我的 XPath 查询(抓取 HTML 表)只能在 Firebug 中工作,而不能在我正在开发的应用程序中工作? [英] Why does my XPath query (scraping HTML tables) only work in Firebug, but not the application I'm developing?

查看:17
本文介绍了为什么我的 XPath 查询(抓取 HTML 表)只能在 Firebug 中工作,而不能在我正在开发的应用程序中工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这旨在为每周出现一次或两次的所有类似(但过于具体的问题而无法成为目标候选人)提供规范的问答.

我正在开发一个应用程序,需要解析包含表格的网站.由于为抓取网页而导出 XPath 表达式是一项枯燥且容易出错的工作,因此我想为此使用 Firebug 的 XPath 提取器功能(或其他浏览器中的类似工具).

I'm developing an application that needs to parse a website with tables in it. As deriving XPath expression for scraping web pages is boring and error-prone work, I'd like to use the XPath extractor feature of Firebug (or similar tools in other browsers) for this.

示例输入如下所示:

<!-- 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 表达式

I want to extract the first data cell ("foobar"). Firebug proposes the XPath expression

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

哪个在任何 XPath 测试器插件中都可以正常工作,但在我自己的应用程序中却没有(未找到结果).如果我将查询减少到 //table[@id],它会再次工作.

which works fine in any XPath tester plugins, but not my own application (no results found). If I cut down the query to //table[@id], it works again.

怎么了?

推荐答案

问题:DOM 需要 标签

Firebug、Chrome 的开发者工具、JavaScript 中的 XPath 函数和其他函数适用于 DOM,而不是基本的 HTML 源代码.

The Problem: DOM Requires <tbody/> Tags

Firebug, Chrome's Developer Tool, XPath functions in JavaScript and others work on the DOM, not the basic HTML source code.

HTML 的 DOM 要求所有未包含在页脚 (<thead/>, <tfoot/>) 的表头中的表行包含在表体标签 中.因此,如果在解析 (X)HTML 时缺少此标记,浏览器会添加该标记.例如,Microsoft 的 DOM 文档

The DOM for HTML requires that all table rows not contained in a table header of footer (<thead/>, <tfoot/>) are included in table body tags <tbody/>. Thus, browsers add this tag if it's missing while parsing (X)HTML. For example, Microsoft's DOM documentation says

tbody 元素对所有表格都公开,即使表格没有明确定义 tbody 元素.

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

有一个关于stackoverflow的另一个答案中的深入解释.

另一方面,HTML 不一定需要该标签使用:

TBODY 开始标记总是需要的,除非表格只包含一个表格主体并且没有表格头部或表格部分.

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/> 标签.还有 HTML 解析器库,如 只输出 XHTML,而不是 "DOM-HTML".

Most XPath Processors Work on raw XML

Excluding JavaScript, most XPath processors work on raw XML, not the DOM, thus do not add <tbody/> tags. Also HTML parser libraries like tag-soup and htmltidy only output XHTML, not "DOM-HTML".

这是一个在 Stackoverflow 上发布的常见问题,适用于 PHP、Ruby、Python、Java、C#、Google Docs(电子表格)和许多其他人.Selenium 在浏览器中运行并在 DOM 上运行——因此它不受影响!

This is a common problem posted on Stackoverflow for PHP, Ruby, Python, Java, C#, Google Docs (Spreadsheets) and lots of others. Selenium runs inside the browser and works on the DOM -- so it is not affected!

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

Compare the source shown by Firebug (or Chrome's Dev Tools) with the one you get by right-clicking and selecting "Show Page Source" (or whatever it's called in your browsers) -- or by using curl http://your.example.org on the command line. Latter will probably not contain any <tbody/> elements (they're rarely used), Firebug will always show them.

检查您卡在的表格中是否真的不包含 <tbody/> 元素(请参阅最后一段).如果是这样,您可能会遇到另一种问题.

Check if the table you're stuck at really does not contain a <tbody/> element (see last paragraph). If it does, you've probably got another kind of problem.

现在删除 /tbody 轴步骤,因此您的查询将如下所示

Now remove the /tbody axis step, so your query will look like

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

解决方案2:跳过标签

这是一个相当脏的解决方案,对于嵌套表可能会失败(可以跳转到内部表).我只会在极少数情况下推荐这样做.

Solution 2: Skip <tbody/> Tags

This is a rather dirty solution and likely to fail for nested tables (can jump into inner tables). I would only recommend to to this in very rare cases.

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

Replace the /tbody axis step by a descendant-or-self step:

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

解决方案 3:允许输入有和没有 标签

如果您事先不确定您的表格或在HTML 源"和 DOM 上下文中使用查询;并且不想/不能使用解决方案 2 中的 hack,提供替代查询(对于 XPath 1.0)或使用可选"轴步骤(XPath 2.0 及更高版本).

Solution 3: Allow Both Input With and Without <tbody/> Tags

If you're not sure in advance that your table or use the query in both "HTML source" and DOM context; and don't want/cannot use the hack from solution 2, provide an alternative query (for XPath 1.0) or use an "optional" axis step (XPath 2.0 and higher).

  • XPath 1.0:
    //table[@id="example"]/tr[2]/td[1] |//table[@id="example"]/tbody/tr[2]/td[1]
  • XPath 2.0://table[@id="example"]/(tbody, .)/tr[2]/td[1]

这篇关于为什么我的 XPath 查询(抓取 HTML 表)只能在 Firebug 中工作,而不能在我正在开发的应用程序中工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆