有没有可能用Ruby和Nokogiri来插入JavaScript引擎
Is it possible to plug a JavaScript engine with Ruby and Nokogiri?
我正在编写一个应用程序来抓取一些网站并从中抓取数据。我用Ruby,Curl和Nokogiri来做这个。在大多数情况下,这很简单,我只需要ping一个URL并解析HTML数据。设置非常好。
然而,在某些情况下,网站会根据用户在某些单选按钮上的输入来检索数据。这会调用一些JavaScript,从服务器获取更多的数据。生成的URL和发布的数据由JavaScript代码确定。
是否可以使用:
-
一个JavaScript库以及这个设置,它将能够为我确定执行HTML页面中的JavaScript?
-
除了使用不同的库之外,HTML和JS库是否有一些集成或通信方式?例如,如果点击了一个按钮,Nokogiri需要调用JavaScript,然后JavaScript需要更新Nokogiri。
如果我的方法似乎不是最好的,你的建议是用Ruby在网上构建一个爬行器+抓取器。
编辑:看起来第1点可以使用therubyrace,因为它在代码中嵌入了V8引擎,但有没有2的替代方案?
您正在寻找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 do:上
$ apt-get install xvfb firefox
您还需要watir-webdriver
和headless
宝石,所以也可以安装它们:
$ 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/
水豚+PhantomJS
我最喜欢的Ruby控制的无头浏览器是PhantomJS。PhantomJS是一款基于WebKit的无头浏览器。它包括Poltergeist,它是Capybara的司机。
总之,堆栈如下所示:
Capybara -> Poltergeist -> PhantomJS -> WebKit
请注意,您可以将PhantomJS直接与硒网络驱动程序一起使用,但Capybara API更好(IMHO)。
作为一个最小的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
除了标准的水豚功能外,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.
Celerity
如果你真的想获得尽可能多的性能,并且不介意切换到JRuby,我发现Celerity速度极快。
Celerity是Java的HTMLUnit的包装器。它速度很快,因为HTMLUnit不是一个完整的浏览器,它更像是一个执行JavaScript的模拟器。缺点是,它不支持完整浏览器所支持的所有JavaScript,因此它不会支持大量JS的网站,但它对大多数网站来说已经足够了,而且一直在变得更好。
另一个优点是JRuby的多线程特性。使用Peach(每个并行)gem,您可以并行启动许多浏览器。我过去用过一个测试套件来完成这项工作,大大缩短了完成的时间。事实上,我们使用Celerity+Peach制作了一个负载测试仪,它比典型的JMeter、Grinder、apachebench等复杂得多。它真的可以锻炼我们的网站!
- 从数据库中获取数据并插入JavaScript变量
- Android,如何将活动中的参数插入JavaScript
- 如何使用DOMDocument将PHP变量插入javascript部分
- 在 IE8 中运行时插入 JavaScript
- 在帖子的网格循环之间插入Javascript(Adsense)
- Smarty-可以't将变量内容插入javascript
- 如何在网页中插入Javascript
- 将值插入JavaScript文件模板并生成新文件
- 有没有可能用Ruby和Nokogiri来插入JavaScript引擎
- 如何将PHP截图插入Javascript脚本
- 在兄弟姐妹周围插入 Javascript 环绕
- 将 json_encode() 数组插入 javascript 函数
- 在 LI 中插入 JavaScript DIV
- 如何在 css 链接标签中插入 javascript 函数
- 如何[专业/正确的方式]将PHP代码插入JavaScript和/或HTML
- 如何在 zend_form 中将数组插入 JavaScript
- 在 html 中插入 javascript 保留表单
- 插入 javascript 变量作为背景图像源
- 如何在浏览器正在加载的页面中插入Javascript
- 将变量插入 JavaScript 函数中的 DIV 中