为什么Ruby中的curl比命令行卷曲慢?

Sti*_*ivi 7 ruby curl http download curb

我试图下载超过1米的页面(以序列ID结尾的URL).我已经实现了一种具有可配置数量的下载线程和一个处理线程的多用途下载管理器.下载器批量下载文件:

curl = Curl::Easy.new

batch_urls.each { |url_info|
    curl.url = url_info[:url]
    curl.perform
    file = File.new(url_info[:file], "wb")
    file << curl.body_str
    file.close
    # ... some other stuff
}
Run Code Online (Sandbox Code Playgroud)

我试过下载8000页样本.使用上面的代码时,我在2分钟内得到1000.当我将所有URL写入文件并在shell中执行时:

cat list | xargs curl
Run Code Online (Sandbox Code Playgroud)

我在两分钟内生成了所有8000页.

事情是,我需要它在ruby代码中,因为有其他监视和处理代码.

我试过了:

  • Curl :: Multi - 它以某种方式更快,但错过了50-90%的文件(不下载它们并且没有给出原因/代码)
  • 使用Curl :: Easy的多个线程 - 与单线程的速度大致相同

为什么重用Curl :: Easy比后续命令行curl调用慢,如何让它更快?或者我做错了什么?

我更喜欢修复我的下载管理器代码,而不是以不同的方式为这种情况下载.

在此之前,我正在调用命令行wget,我提供了一个包含URL列表的文件.Howerver,并非所有错误都得到了处理,在使用URL列表时也无法单独为每个URL指定输出文件.

现在在我看来,最好的方法是使用系统调用'curl'命令的多个线程.但是为什么我可以在Ruby中直接使用Curl?

下载管理器的代码在这里,如果它可能会有所帮助:下载管理器(我玩过超时,从未将其设置为各种值,它似乎没有帮助)

任何提示赞赏.

Jon*_*röm 5

这对Typhoeus来说可能是一个合适的任务

像这样(未经测试):

require 'typhoeus'

def write_file(filename, data)
    file = File.new(filename, "wb")
    file.write(data)
    file.close
      # ... some other stuff
end

hydra = Typhoeus::Hydra.new(:max_concurrency => 20)

batch_urls.each do |url_info|
    req = Typhoeus::Request.new(url_info[:url])
    req.on_complete do |response|
      write_file(url_info[:file], response.body)
    end
    hydra.queue req
end

hydra.run
Run Code Online (Sandbox Code Playgroud)

想想看,由于文件庞大,你可能会遇到内存问题.防止这种情况的一种方法是永远不会将数据存储在变量中,而是直接将其传输到文件中.您可以使用em-http-request.

EventMachine.run {
  http = EventMachine::HttpRequest.new('http://www.website.com/').get
  http.stream { |chunk| print chunk }
  # ...
}
Run Code Online (Sandbox Code Playgroud)