使用Watir在Ruby中抓取和/或解析HTML流量?

时间:2013-10-09 23:34:46

标签: html css ruby mechanize watir

在使用Watir和Mechanize解析自动化浏览器时,我遇到了一些我希望能够从页面中提取的数据(以及来自其他页面的类似数据),如下所示:

<data>
<somehtmltags>
<tr style="cursor:auto"><td class="hyperlink-first" style="padding-top:20px">Title1</td><td style="padding-top:20px">Data: <br/>Data2: <br/>Data3: <br/>Data4: <br/></td><td style="text-align:center;"><img alt="SomeData" border="0" height="100" src="servlet/Chart?filename=jfreechart-onetime-tmp.png" style="position:static" width="580"/></td></tr>
<tr style="cursor:auto"><td class="hyperlink-first" style="padding-top:20px">Title2</td><td style="padding-top:20px">Data: <br/>Data2: <br/>Data3: <br/>Data4: <br/></td><td style="text-align:center;"><img alt="SomeData" border="0" height="100" src="servlet/Chart?filename=jfreechart-onetime-tmp.png" style="position:static" width="580"/></td></tr>
<somemorehtmltags>
<more data>

我的问题是,在Ruby中使用Watir,Mechanize,Nokogiri或类似方法 - 有没有更简单的方法可以指定我想在HTML代码中使用一组特定的匹配标记并将其保存在其他地方?

所以在这个例子中,我想搜索一组标题为“Title1”的标签,并将该部分代码保存为字符串(包括标签)?

2 个答案:

答案 0 :(得分:3)

我对您的问题的解释是,您希望单元格(td元素)的html与单元格(td元素)相邻,文本为“Title1”。在您的示例代码中,这将意味着第一个tr元素中的第二个td元素。

假设解释正确,您可以执行以下操作。请注意,您可以在任何Watir元素上使用.html方法来获取其html(作为可以保存为变量的字符串)。

#Find the cell with Title1 and then get the second cell in that row
html = browser.td(:text => 'Title1').parent.td(:index => 1).html
#=> "<td style=\"padding-top:20px\">Data: <br>Data2: <br>Data3: <br>Data4: <br></td>"

如果您想要整个行,包括标题,您可以获得Title1元素的父级:

html = browser.td(:text => 'Title1').parent.html
#=> "<tr style=\"cursor:auto\"><td class=\"hyperlink-first\" style=\"padding-top:20px\">Title1</td><td style=\"padding-top:20px\">Data: <br>Data2: <br>Data3: <br>Data4: <br></td><td style=\"text-align:center;\"><img alt=\"SomeData\" src=\"servlet/Chart?filename=jfreechart-onetime-tmp.png\" style=\"position:static\" border=\"0\" height=\"100\" width=\"580\"></td></tr>"

以上假设您想要获得的页面上只有1个Title1元素。如果可能有多个,那么您将需要创建一个包含文本Title1的td元素集合,然后为每个元素收集兄弟元素。这将为您提供一系列字符串。

html = browser.tds(:text => 'Title1').collect do |td| 
    td.parent.td(:index => 1).html
end
#=> ["<td style=\"padding-top:20px\">Data: <br>Data2: <br>Data3: <br>Data4: <br></td>", 
#=> "<td style=\"padding-top:20px\">Data: <br>Data2: <br>Data3: <br>Data4: <br></td>"]

如果Jano的解释是正确的并且您想要所有标题都是“Title”的行(即“Title1”,“Title2”等),您可以使用正则表达式进行部分文本匹配。以下内容将为您提供第一个单元格如Title的每一行。

html = browser.tds(:text => /^Title\d$/).collect do |td| 
    td.parent.html
end
#=> ["<tr style=\"cursor:auto\"><td class=\"hyperlink-first\" style=\"padding-top:20px\">Title1</td><td style=\"padding-top:20px\">Data: <br>Data2: <br>Data3: <br>Data4: <br></td><td style=\"text-align:center;\"><img alt=\"SomeData\" src=\"servlet/Chart?filename=jfreechart-onetime-tmp.png\" style=\"position:static\" border=\"0\" height=\"100\" width=\"580\"></td></tr>",
#=> "<tr style=\"cursor:auto\"><td class=\"hyperlink-first\" style=\"padding-top:20px\">Title2</td><td style=\"padding-top:20px\">Data: <br>Data2: <br>Data3: <br>Data4: <br></td><td style=\"text-align:center;\"><img alt=\"SomeData\" src=\"servlet/Chart?filename=jfreechart-onetime-tmp.png\" style=\"position:static\" border=\"0\" height=\"100\" width=\"580\"></td></tr>"]

答案 1 :(得分:0)

使用ruby和watir,您可以使用正则表达式在html中搜索您的标签。在您的情况下,您可以使用以下内容获取html页面:

my_html_container = @browser.html

...并使用正则表达式和扫描函数来获取标签,例如:

my_tags = my_html_container.scan(/(<tr .*)Title\d(.*tr>)/)

您可以修改正则表达式以获得您想要的内容:)