1

我正在编写一个应用程序来抓取一些网站并从中抓取数据。我正在使用 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 点?

4

2 回答 2

7

您正在寻找运行真实浏览器并允许您在网页上执行您能想到的所有操作的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

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

$ apt-get install xvfb firefox

您还需要watir-webdriverheadlessgems 所以继续安装它们:

$ 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/

于 2012-07-15T19:44:06.223 回答
0

水豚 + 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使用and注入并运行你自己的 javascriptpage.execute_script
  • page.within_framepage.within_window
  • page.status_codepage.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 等要复杂得多。它真的可以锻炼我们的网站!

于 2014-04-14T21:27:49.710 回答