是否可以使用Ruby和Nokogiri插入JavaScript引擎?

我正在编写一个应用程序来抓取一些网站并从中抓取数据。 我正在使用Ruby,Curl和Nokogiri来做这件事。 在大多数情况下,它很简单,我只需要ping一个URL并解析HTML数据。 设置完美无缺。

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

是否可以使用:

  1. 一个JavaScript库以及这个设置,它能够确定在我的HTML页面中执行JavaScript吗?

  2. 除了使用不同的库之外,还有一些集成或HTML和JS库进行通信的方式吗? 例如,如果单击一个按钮,Nokogiri需要调用JavaScript,然后JavaScript需要更新Nokogiri。

如果我的方法看起来不是最好的,那么你的建议是使用Ruby在Web上构建一个crawler + scraper。

编辑:使用therubyrace看起来像第1点是可能的,因为它在你的代码中嵌入了V8引擎,但有2个替代吗?

您正在寻找运行真实浏览器的Watir ,并允许您在网页上执行您能想到的每个操作。 还有一个名为Selenium的类似项目。

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

Watir无头的例子

假设我们有这个HTML:

Hello from HTML

这个Javascript:

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

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

而你想获得动态插入的文本。 首先,你需要一个安装了xvfbfirefox的Linux机器,例如在Ubuntu上:

 $ apt-get install xvfb firefox 

你还需要watir-webdriverheadlessgem,所以继续安装它们:

 $ 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 

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

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

Capybara + PhantomJS

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

总之,堆栈看起来像这样:

 Capybara -> Poltergeist -> PhantomJS -> WebKit 

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

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

刮取google结果链接的示例代码:

 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 

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

  • 使用page.evaluate_scriptpage.execute_script注入并运行您自己的javascript
  • 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处理
  • 拖和下降

这些function在Poltergeist GitHub页面上列出: https : //github.com/teampoltergeist/poltergeist 。

迅捷

如果你真的想尽可能多地提高性能,并且不介意切换到JRuby这样做,我发现Celerity超级快。

Celerity是Java的HTMLUnit的包装器。 它很快,因为HTMLUnit不是一个完整的浏览器,它更像是一个执行JavaScript的模拟器。 缺点是它不支持完整浏览器所做的所有JavaScript,因此它不支持非常重的JS网站,但它足以满足大多数网站并且一直在变得更好。

另一个优点是JRuby的multithreading特性。 使用Peach(并行每个)gem ,您可以并行启动许多浏览器。 我过去使用测试套件完成了这项工作,并大大缩短了完成时间。 实际上,我们使用Celerity + Peach制作了一个负载测试仪,它比典型的JMeter,Grinder,apachebench等更复杂。它可以真正运用我们的网站!