【问题标题】:Is it possible to plug a JavaScript engine with Ruby and Nokogiri? [closed]是否可以使用 Ruby 和 Nokogiri 插入 JavaScript 引擎? [关闭]
【发布时间】:2012-07-14 18:01:17
【问题描述】:

我正在编写一个应用程序来抓取一些网站并从中获取数据。我正在使用 Ruby、Curl 和 Nokogiri 来执行此操作。在大多数情况下,这很简单,我只需要 ping 一个 URL 并解析 HTML 数据。设置工作得很好。

但是,在某些情况下,网站会根据用户在某些单选按钮上的输入来检索数据。这会调用一些 JavaScript 从服务器获取更多数据。生成的 URL 和发布的数据由 JavaScript 代码确定。

是否可以使用:

  1. 一个 JavaScript 库以及此设置能够为我确定在 HTML 页面中执行 JavaScript?

  2. 除了使用不同的库之外,HTML 和 JS 库是否有某种集成或通信方式?例如,如果单击按钮,Nokogiri 需要调用 JavaScript,然后 JavaScript 需要更新 Nokogiri。

如果我的方法看起来不是最好的,您的建议是使用 Ruby 在网络上构建一个爬虫 + 爬虫。

编辑:看起来第 1 点可以使用 therubyrace,因为它将 V8 引擎嵌入到您的代码中,但是否有替代 2 的方法?

【问题讨论】:

    标签: javascript ruby web-scraping web-crawler nokogiri


    【解决方案1】:

    您正在寻找Watir,它运行真正的浏览器并允许您在网页上执行您能想到的所有操作。有一个类似的项目叫做Selenium。

    您甚至可以在 Linux 机器上将 Watir 与所谓的“无头”浏览器一起使用。

    Watir 无头示例

    假设我们有这个 HTML:

    <p id="hello">Hello from HTML</p>
    

    还有这个 Javascript:

    document.getElementById('hello').innerHTML = 'Hello from JavaScript';
    

    (演示:http://jsbin.com/ivihur)

    并且您想要获取动态插入的文本。首先,您需要一个安装了xvfb 和firefox 的Linux 机器,例如在Ubuntu 上:

    $ apt-get install xvfb firefox
    

    您还需要 watir-webdriver 和 headless gem,所以请继续安装它们:

    $ gem install watir-webdriver headless
    

    然后你可以从页面中读取动态内容,如下所示:

    require 'rubygems'
    require 'watir-webdriver'
    require 'headless'
    
    headless = Headless.new
    headless.start
    browser = Watir::Browser.new
    
    browser.goto 'http://jsbin.com/ivihur' # our example
    el = browser.element :css => '#hello'
    puts el.text
    
    browser.close
    headless.destroy
    

    如果一切顺利,这将输出:

    Hello from JavaScript
    

    我知道这也会在后台运行浏览器,但这是我能想到的最简单的解决您问题的方法。启动浏览器需要相当长的时间,但随后的请求非常快。 (运行goto 然后多次获取上面的动态文本对于我的 Rackspace 云服务器上的每个请求大约需要 0.5 秒)。

    来源:http://watirwebdriver.com/headless/

    【讨论】:

    • 感谢您的帮助。 Watir 和 Selenium 都是试图模仿用户交互的测试工具。我需要用它来抓取网站数据,并希望它能够快速运行。你有什么建议吗?
    • 还有 HTMLUnit (htmlunit.sourceforge.net),它在不打开浏览器窗口的情况下执行基本相同的操作。不过它有自己的专有 JavaScript 引擎,因此它可能具有与其他浏览器不同的行为。此外,它是Java。到目前为止,我仍然认为 Watir 是 Plain Ruby 中最简单的解决方案。
    • 您也可以将 headless gem 与 watir 一起使用,请参阅我的编辑示例。
    • 还有更多!这似乎也很有趣:gist.github.com/1430686,以及github.com/Zapotek/dom-js-experiment
    • 我一定会试一试的。非常感谢您的努力!
    【解决方案2】:

    水豚 + PhantomJS

    我最喜欢的 Ruby 控制的无头浏览器是 PhantomJS。 PhantomJS 是一个基于 WebKit 的无头浏览器。它包括 Poltergeist,它是 Capybara 的驱动程序。

    总而言之,堆栈如下所示:

    Capybara -> Poltergeist -> PhantomJS -> WebKit
    

    请注意,您可以直接将 PhantomJS 与 selenium-webdriver 一起使用,但 Capybara API 更好(恕我直言)。

    作为最小的 WebKit 实现,PhantomJS 的启动时间比 Chrome 或 IE 等完整浏览器更快。

    抓取谷歌结果链接的示例代码:

    module Test
      class Google
        include Capybara::DSL
    
        def get_results
          visit('/')
          fill_in "q", :with => "Capybara"
          click_button "Google Search"
          all(:xpath, "//li[@class='g']/h3/a").each { |a| puts a[:href] }
    
        end
      end
    end
    
    scraper = Test::Google.new
    scraper.get_results
    

    除了标准的Capybara功能外,Poltergeist还可以做一些非常方便的事情:

    • 使用page.evaluate_script 和page.execute_script 注入并运行您自己的javascript
    • page.within_frame 和 page.within_window
    • page.status_code 和 page.response_headers
    • page.save_screenshot
    • page.driver.render_base64(format, options)
    • page.driver.scroll_to(left, top)
    • page.driver.basic_authorize(user, password)
    • element.native.send_keys(*keys)
    • cookie 处理
    • 拖放

    Poltergeist GitHub 页面上列出了这些功能:https://github.com/teampoltergeist/poltergeist。

    速度

    如果您真的想尽可能提高性能,并且不介意改用 JRuby,我发现 Celerity 非常快。

    Celerity 是 Java 的 HTMLUnit 的包装器。它速度很快,因为 HTMLUnit 不是一个完整的浏览器,它更像是一个执行 JavaScript 的模拟器。缺点是它不支持完整浏览器所支持的所有 JavaScript,因此它不会支持非常重 JS 的网站,但对于大多数网站来说已经足够了,并且一直在变得更好。

    另一个优点是 JRuby 的多线程特性。使用Peach (parallel each) gem,您可以并行启动许多浏览器。我过去曾使用测试套件完成此操作,并大大减少了完成时间。事实上,我们使用 Celerity + Peach 制作了一个负载测试器,它比典型的 JMeter、Grinder、apachebench 等要复杂得多。它真的可以锻炼我们的网站!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-12
      • 2010-09-15
      • 2013-01-15
      • 1970-01-01
      • 1970-01-01
      • 2011-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多