屏幕抓取网页,使用Mechanize显示数据页面

时间:2009-03-21 18:40:41

标签: ruby screen-scraping paging mechanize

我正在尝试屏幕抓取一个网页(使用Mechanize),它在网格页面中显示记录。我能够读取第一页中显示的值,但现在需要导航到下一页以读取适当的值。

<tr>
    <td><span>1</span></td>
    <td><a href="javascript:__doPostBack('gvw_offices','Page$2')">2</a></td>
    <td><a href="javascript:__doPostBack('gvw_offices','Page$3')" >3</a></td>
    <td><a href="javascript:__doPostBack('gvw_offices','Page$4')" >4</a></td>
    <td><a href="javascript:__doPostBack('gvw_offices','Page$5')" >5</a></td>
    <td><a href="javascript:__doPostBack('gvw_offices','Page$6')">6</a></td>
    <td><a href="javascript:__doPostBack('gvw_offices','Page$7')" >7</a></td>
    <td><a href="javascript:__doPostBack('gvw_offices','Page$8')">8</a></td>
    <td><a href="javascript:__doPostBack('gvw_offices','Page$9')" >9</a></td>
    <td><a href="javascript:__doPostBack('gvw_offices','Page$10')" >10</a></td>
    <td><a href="javascript:__doPostBack('gvw_offices','Page$11')">...</a></td>
</tr>

我能够通过所有链接但是当我尝试这个时: -

links = (row/"a")
links.each do |link|
    agent.click link.attributes['href']   # This fails 
    agent.click link   # This also fails
end

原因是agent.click期望将URL作为参数。

有没有一种方法可以在页面显示时读取所有值?如果不是,当href是回发而不是URL时,我们怎么能有这样的点击动作?

4 个答案:

答案 0 :(得分:5)

Mechanize无法处理javascript,所以基本上你有两个选择:

  • 使用scrubyt和firewatir:这是一种编写浏览器脚本的方法(因此Firefox处理javascript部分)
  • 手动检查基本网址并动态添加页码

类似的东西:

base_url = 'http://example.com/gvw_offcies&page='
links.each do |link|
  page_number = ... #get the page number from link
  agent.get base_url+page_number
end

答案 1 :(得分:1)

我过去曾尝试过的所有解决方案都持续了很长一段时间(特别是Celerity),但我的结论是,它们都非常可怕并且有严重的缺点,因为它们基于相同的生活而非常困难用于处理Javascript的HtmlUnit引擎。

Celerity不是一个屏幕抓取工具,它在Windows Management中缺乏,并且基于HTMLUNIT引擎,它在处理Javascript方面一点也不擅长。但是,对于使用最低到中等级别的Javascript和AJAX请求的站点,它可以快速运行。它基于ruby,对那些不喜欢Java的人来说是一种解脱。

您最好的选择是使用Selenium WebDriver API。这需要在你的linux服务器上显示X并且它比HtmlUnit慢,但它不会惹你很多问题,你将使用任何派生或包装HtmlUnit。有一个选项可以使用HtmlUnit,但你牺牲了准确性,速度的一致性。对于抓取来说,HtmlUnit的速度要快得多。

然而,抓住其他不属于您的网站速度总是不是一件好事,因为它通常会保证IP禁令。

我个人的建议是使用HtmlUnit引擎保持清晰,并使用Selenium直接远程控制您选择的浏览器,以获得最高的准确性和可靠性。

答案 2 :(得分:0)

我会使用类似webscarab之类的内容来查看POST请求Javascript实际执行的位置。特别是对于AJAX的东西,无论如何它们只是HTTP请求 只需启动它并将其设置为Firefox中的代理。大多数情况下,您可以看到某种模式并直接刮掉这些URL

答案 3 :(得分:0)

您可以尝试在Jruby中使用Celerity并将页面传递给HTML解析库。 Celerity应该与Watir API兼容,并且是HtmlUnit的包装器。我正在使用mechanize进行数据收集,但是必须切换到在JS中生成的一些站点。

http://celerity.rubyforge.org/