1

我正在使用 HPricot 的 css 搜索来识别网页中的表格。这是我正在解析的示例 html 片段:

<table height=61 width=700>
<tbody>
<tr>
<td><font size=3pt color = 'Blue'><b><A NAME=a1>Some header text</A></b></font></td></tr>
 ...
</tbody></table>

页面中有很多表格。我想找到包含A Name=a1参考的表。现在,我这样做的方式是

(page/"a[@name=a1]")[0].parent.parent.parent.parent.parent

我不喜欢这个,因为

  • 很丑
  • 它容易出错(如果维护网页的人删除了 tbody 怎么办?)

有没有办法告诉 hpricot 让我得到指定元素的表祖先?

编辑:这是我正在解析的完整页面:http: //www.blonnet.com/businessline/scoboard/a.htm

我感兴趣的是两张表,一张是季度业绩,另一张是年度业绩。现在,我提取这些表的方法是查找并从那里向上移动。

4

2 回答 2

1

罗希特是对的。它很丑陋,而且容易出错(超出了它的需要)。再次正如他所说,更清楚地说“找到最接近的父母是一张桌子”,这可能适用于任何孩子/父母的关系。

如果用 hpricot 做到这一点是“不可能的”,那么就这么说吧。但不要只是说“无论如何尝试这样做是没有希望的,有什么意义”。这是一个虚假的答案。它也无助于下一个出现的人(我自己)寻找同一个问题的答案,但出于不同的原因,这正在解析许多页面,其中假设存在差异,而不仅仅是担心。

要真正回答这个问题……我还不知道。而且我不太希望通过 hpricot 找出答案。该文档绝对不存在。

但这里有一个解决方法可以做同样的事情。

table = (page%"a[@name=a1]").parent
table = table.parent while table.name != "table"
于 2011-09-18T23:13:22.077 回答
0

如果没有看到整个页面,很难给出明确的答案,但通常你的方式是正确的答案。你必须找到一个像样的地标,然后从那里导航,如果它涉及备份链条,那么这就是你要做的。

您也许可以使用 XPATH 来查找表,然后在其中查找链接,但这并不能真正改善事情,它只会改变它们。Firebug 是 Firefox 插件,可以轻松获取页面中元素的 XPATH,因此您可以找到有问题的表并让 Firebug 向您显示路径,或者只需右键单击 xpath 中的节点即可复制它显示,然后将其添加到您的查找中。

“它很丑”,好吧,也许吧,但并非所有代码都是美丽或优雅的,因为并非所有问题都适合美丽和/或优雅的解决方案。有时我们必须对“它有效”感到满意。只要它可靠地工作并且您知道为什么,那么您就领先于许多其他编码器。

“...如果维护网页的人删除了 tbody 怎么办?”,几乎所有的 HTML 或 XML 解析都会遇到同样的问题,因为我们无法控制源。您尽可能地编写代码,注释如果内容更改可能会失败的地方,然后交叉手指继续前进。即使您从 TPS 报告中解析表格数据,您也可能遇到同样的问题。

我建议做的唯一不同的事情是使用%(AKA "at") 而不是/(AKA search)。%仅返回第一次出现,因此您可以删除[0]索引。

(page%"a[@name=a1]").parent.parent.parent.parent.parent

或者

page%'//a[@name="a1"]/../../../../../..'

它使用 XPath 引擎来后退链。如果考虑速度,那应该会快一点。

如果您知道目标表是唯一具有该宽度和高度的表,则可以使用更具体的 xpath:

page%'//table[@height=61 and @width=700]'

我推荐 Nokogiri 而不是 Hpricot。


您还可以从文档顶部向下使用 XPath:

irb(main):039:0> print (doc/'//body/table[2]/tr/td[2]/table[2]').to_html[0..100]
<table height="61" width="700"><tbody>
<tr><td width="700" colspan="7" align="center"> <font size="3p=> nil

基本上,XPath 模式意味着:

找到 body 标记,然后是第三个表,然后是其行的第三个单元格。在单元格中找到第三个表。

注意:Firefox 会自动将<tbody>标签添加到源代码中,即使收到的 HTML 文件中没有该标签。尝试使用 Firefox 查看源代码以开发您自己的 XPath 时,这真的会让您一头雾水。

您之后的另一张表是/html/body/table[2]/tbody/tr/td[2]/table[3]根据 Firefox 的,因此您必须删除tbody. 你也不需要锚定在/html.

于 2010-10-23T09:28:19.940 回答