如何同时运行多个nokogiri屏幕刮线程

时间:2011-03-21 13:22:37

标签: ruby-on-rails screen-scraping nokogiri

我有一个网站,要求在许多不同的网站上使用Nokogiri来提取数据。此过程使用delayed_job gem作为后台作业运行。但是,每页运行大约需要3-4秒,因为它必须暂停并等待其他网站响应。 我目前只是通过基本上说

来运行它们
Websites.all.each do |website|
  # screen scrape
end

我想分批执行它们而不是每个执行它们,这样我就不必等待每个站点的服务器响应(可能需要20秒才能完成)。

最好的ruby或rails方法是什么?

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:5)

您可能需要查看Typhoeus,这样才能生成并行的http请求。

我发现a short blawg post here与Nokogiri一起使用它,但我自己没试过。

包装在DJ中,这应该可以解决很少的客户端延迟问题。

答案 1 :(得分:2)

您需要使用延迟工作。看看这个Railscasts

请记住,大多数主机会对此类事件收费。

如果您不关心管理线程,也可以使用spawn插件,但它更容易!

这就是你需要做的所有事情:

  1. rails plugin/install https://github.com/tra/spawn.git
  2. 然后在您的控制器或模型中添加方法
  3. 例如:

     spawn do
        #execute your code here :)
     end 
    

    http://railscasts.com/episodes/171-delayed-job

    https://github.com/tra/spawn

答案 2 :(得分:2)

我正在使用EventMachine为当前项目做类似的事情。有一个很棒的插件叫做em-http-request,它允许你并行地发出多个HTTP请求,并提供同步响应的选项。

来自the em-http-request github docs:

EventMachine.run {
  http1 = EventMachine::HttpRequest.new('http://google.com/').get
  http2 = EventMachine::HttpRequest.new('http://yahoo.com/').get

  http1.callback { }
  http2.callback { } 
end

所以在你的情况下,你可以

callbacks = []
Websites.all.each do |website|
    callbacks << EventMachine::HttpRequest.new(website.url).get
end

callbacks.each do |http|
    http.callback { }
end

使用瘦Web服务器运行rails应用程序,以获得正常运行的EventMachine循环:

bundle exec rails server thin

您还需要eventmachine和em-http-request宝石。祝你好运!