HPricot css search:如何使用字符串选择器选择特定元素的父/祖先?

时间:2010-10-23 06:48:12

标签: ruby css-selectors hpricot

我正在使用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

我不喜欢这个,因为

  • 很难看
  • 这很容易出错(如果维护网页的人删除了这个?)

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

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

我感兴趣的是两个表,一个是季度结果,另一个是年度结果。现在,我正在提取这些表的方式是找到并从那里向上移动。

2 个答案:

答案 0 :(得分:1)

罗宾是对的。它很丑陋而且容易出错(比需要更多)。再次正如他所说的更为清楚,意图说“找到最近的父母就是一张桌子”,这可以用于任何子/父关系。

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

要真正回答这个问题......我还不知道。而且我没有太多希望找到hpricot。文档绝对不可能存在。

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

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

答案 1 :(得分:0)

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

您可以使用XPATH查找表,然后在其中查找链接,但这并没有真正改进,它只会更改它们。 Firebug,Firefox插件,可以轻松地将XPATH添加到页面中的元素,因此您可以找到有问题的表并让Firebug显示路径,或者只需通过右键单击xpath中的节点来复制它显示,并将其过去进入查找。

“这很难看”,也许,但并非所有代码都是美丽或优雅的,因为并非所有问题都适用于美观和/或优雅的解决方案。有时我们必须对“它有效”感到高兴。只要它可靠地工作,你就知道为什么你会领先于许多其他程序员。

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

我建议采取不同的做法,就是使用%(AKA“at”)代替/(AKA搜索)。 %仅返回第一个匹配项,因此您可以删除[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。

根据Firefox,你所追求的另一张桌子是/html/body/table[2]/tbody/tr/td[2]/table[3],所以你必须剥离tbody。您也不需要在/html锚定。