我正在尝试使用以下Ruby脚本通过HTTP下载二进制文件。
#!/usr/bin/env ruby
require 'net/http'
require 'uri'
def http_download(resource, filename, debug = false)
uri = URI.parse(resource)
puts "Starting HTTP download for: #{uri}"
http_object = Net::HTTP.new(uri.host, uri.port)
http_object.use_ssl = true if uri.scheme == 'https'
begin
http_object.start do |http|
request = Net::HTTP::Get.new uri.request_uri
Net::HTTP.get_print(uri) if debug
http.read_timeout = 500
http.request request do |response|
open filename, 'w' do |io|
response.read_body do |chunk|
io.write chunk
end
end
end
end
rescue Exception => e
puts "=> Exception: '#{e}'. Skipping download."
return
end
puts "Stored download as #{filename}."
end
然而,它下载HTML源代码而不是二进制代码。当我在浏览器中输入URL时,将下载二进制文件。以下是脚本失败的URL:
http://dcatlas.dcgis.dc.gov/catalog/download.asp?downloadID=2175&downloadTYPE=KML
我按如下方式执行脚本
pry> require 'myscript'
pry> resource = "http://dcatlas.dcgis.dc.gov/catalog/download.asp?downloadID=2175&downloadTYPE=KML"
pry> http_download(resource,"StreetTreePt.KML", true)
如何下载二进制文件?
我发现这个redirection check看起来很合理。当我在响应块中集成时,它失败并出现以下错误:
Exception: 'undefined method `host' for "save_download.asp?filename=StreetTreePt.KML":String'. Skipping download.
上面发布的“原始”功能中不会发生异常。
答案 0 :(得分:2)
Net :: HTTP的文档显示how to handle redirects:
重定向后
每个Net :: HTTPResponse对象都属于其响应代码的类。
例如,所有2XX响应都是Net :: HTTPSuccess子类的实例,3XX响应是Net :: HTTPRedirection子类的实例,200响应是Net :: HTTPOK类的实例。有关响应类的详细信息,请参阅下面的“HTTP响应类”部分。
使用案例陈述,您可以正确处理各种类型的答案:
def fetch(uri_str, limit = 10)
# You should choose a better exception.
raise ArgumentError, 'too many HTTP redirects' if limit == 0
response = Net::HTTP.get_response(URI(uri_str))
case response
when Net::HTTPSuccess then
response
when Net::HTTPRedirection then
location = response['location']
warn "redirected to #{location}"
fetch(location, limit - 1)
else
response.value
end
end
print fetch('http://www.ruby-lang.org')
或者,您可以使用Ruby的OpenURI,它会自动处理它。或者,Curb gem将会这样做。可能也是Typhoeus和HTTPClient。
根据您在问题中显示的代码,您获得的例外情况只能来自:
http_object = Net::HTTP.new(uri.host, uri.port)
这几乎不可能,因为uri
是一个URI对象。如果您需要有关该问题的帮助,则需要显示完整的代码。