【问题标题】:Screen scrape web page that displays data page wise using Mechanize屏幕抓取网页,使用 Mechanize 明智地显示数据页面
【发布时间】:2009-03-21 18:40:40
【问题描述】:

我正在尝试屏幕抓取一个网页(使用 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 时,我们怎么能有这样的点击操作??

【问题讨论】:

    标签: ruby screen-scraping paging mechanize


    【解决方案1】:

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

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

    类似:

    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
    

    【讨论】:

    • 问题是这个页面使用 ASP.Grid 来逐页显示记录,因此每个页面的链接都是回发,没有直接的 URL。你是说如果我们在 URL 中添加网格名称和页码,我们可以导致回发(尽管我尝试它时它不起作用)?
    • 我对 ASP.net 不熟悉,但是回发基本上是对当前页面的 POST 请求,不是吗?所以你可以尝试类似 agent.post current_url, {"page_number" => page_number}
    【解决方案2】:

    上述所有解决方案我过去已经尝试了很长时间(尤其是 Celerity),但我的结论是它们都很糟糕并且有严重的缺点,这使得生活变得非常困难,因为它们基于相同的用于处理 Javascript 的 HtmlUnit 引擎。

    Celerity 不是屏幕抓取工具,它缺少 Windows 管理,并且基于 HTMLUNIT 引擎,在处理 Javascript 方面一点也不擅长。但是,它适用于使用最低到中等级别的 Javascript 和 AJAX 请求的站点。它基于 ruby​​,这对于不喜欢 Java 的人来说是一种解脱。

    最好的办法是使用 Selenium WebDriver API。这需要在您的 linux 服务器上显示 X,并且它比 HtmlUnit 慢,但它不会因为使用任何派生或包装 HtmlUnit 时会遇到的许多问题而困扰您。有一个使用 HtmlUnit 的选项,但是你牺牲了准确性和一致性来换取速度。 HtmlUnit 的抓取速度要快得多。

    但是,抓取不属于您的其他网站的速度总是不是一件好事,因为它通常会导致 IP 封禁。

    我的个人建议是远离使用 HtmlUnit 引擎的任何事情,并使用 Selenium 直接远程控制您选择的浏览器以获得最大的准确性和可靠性。

    【讨论】:

      【解决方案3】:

      我会使用 webscarab 之类的东西来简单地查看 Javascript 所做的 POST 请求的实际去向。特别是对于 AJAX 的东西,无论如何它们只是 HTTP 请求。
      只需启动它并将其设置为 Firefox 中的代理。大多数时候,您可以看到某种模式,然后直接抓取这些 URL

      【讨论】:

        【解决方案4】:

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

        http://celerity.rubyforge.org/

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-04
          • 2011-08-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-02-27
          相关资源
          最近更新 更多