【问题标题】:How to download a delayed file via HTTP in Ruby?如何在 Ruby 中通过 HTTP 下载延迟文件?
【发布时间】:2015-07-02 08:28:06
【问题描述】:

我使用以下 Ruby 函数通过 HTTP 下载各种文件:

def http_download(uri, filename)
  bytes_total = nil
  begin
    uri.open(
      read_timeout: 500,
      content_length_proc: lambda { |content_length|
        bytes_total = content_length
      },
      progress_proc: lambda { |bytes_transferred|
        if bytes_total
          print("\r#{bytes_transferred} of #{bytes_total} bytes")
        else
          print("\r#{bytes_transferred} bytes (total size unknown)")
        end
      }
    ) do |file|
      open filename, 'w' do |io|
        file.each_line do |line|
          io.write line
        end
      end
    end
  rescue => e
    puts e
  end
end

我还想从this website 下载文件(csvkmlzipgeojson)。但是,设置了某种延迟。当我在浏览器中单击下载链接时,需要一些时间才能出现下载窗口。我想该文件需要先在服务器上进行处理才能提供服务。

如何修改我的脚本以考虑延迟?

我正在运行 Ruby 2.2.2。

【问题讨论】:

  • 您好,您的 Ruby 版本是多少?我正在使用 Ruby 2.2.2 运行您的代码,但出现“调用私有方法 'open'”的异常。我已经打开了网站,你点击的是“下载数据集”按钮吗?我没有遇到你提到的延迟,只是网站url附加了.csv.kml.zip和几个查询参数。
  • 是的,最新版本。是的,链接隐藏在“下载数据集”按钮下。也许,现在我点击了它,他们在服务器上缓冲了它。不妨试试另一个数据集。
  • 我发现,对于您第一次请求的数据集,它会返回一个表示状态的 JSON,例如。 { status: "processing", processing_time: 0, count: 0 }{ status: "processing", processing_time: 9.58, count: 0 }。处理后,您将下载文件。所以我认为您可以添加一个判断并在处理部分重试。
  • 正确。加评委是什么意思?

标签: ruby download delay open-uri


【解决方案1】:

这里是根据帖子和评论的修改:

require 'open-uri'

def http_download(uri, filename)
  bytes_total = nil
  index = 1
  begin
    open(
      uri,
      read_timeout: 500,
      content_length_proc: lambda { |content_length|
        bytes_total = content_length
      },
      progress_proc: lambda { |bytes_transferred|
        if bytes_total
          print("\r#{bytes_transferred} of #{bytes_total} bytes")
        else
          print("\r#{bytes_transferred} bytes (total size unknown)")
        end
      }
    ) do |io|
      # if "application/json" == io.content_type
      if io.is_a? StringIO
        raise " --> Failed, server is processing. Retry the request ##{index}"
      else # Tempfile
        puts "\n--> Succeed, writing to #{filename}"
        File.open(filename, 'w'){|wf| wf.write io.read}
      end
    end
  rescue => e
    puts e
    return if e.is_a? OpenURI::HTTPError # Processing error

    index += 1
    return if index > 10

    sleep index and retry
  end
end

【讨论】:

  • 太棒了!我注意到的一个小案例是当下载的是 JSON 文件时 - 我在上面添加了链接。
  • 太棒了!我在another server (kml) 上尝试了脚本。出于某种原因,它在那里不起作用,尽管它似乎是相同的延迟机制。你能看出原因吗?
  • 抱歉,我已经完成了我的工作,我想我无法解决所有问题。
  • 明白。尽管在我看来是相同的服务器安装。这就是为什么没有返回奇怪的数据的原因。
猜你喜欢
  • 2010-12-25
  • 1970-01-01
  • 2010-09-06
  • 2021-01-29
  • 1970-01-01
  • 2020-04-04
相关资源
最近更新 更多