Ruby Net::HTTP 超时
Posted
技术标签:
【中文标题】Ruby Net::HTTP 超时【英文标题】:Ruby Net::HTTP time out 【发布时间】:2011-01-14 19:28:17 【问题描述】:我正在尝试编写我的第一个 Ruby 程序,但遇到了问题。该代码必须通过 HTTP 下载 32 个 MP3 文件。它实际上下载了一些,然后超时。
我尝试设置超时时间,但没有任何区别。在 Windows、Cygwin 和 Mac OS X 下运行代码,结果相同。
这是代码:
require 'rubygems'
require 'open-uri'
require 'nokogiri'
require 'set'
require 'net/http'
require 'uri'
puts "\n Up and running!\n\n"
links_set =
pages = ['http://www.vimeo.com/siai/videos/sort:oldest',
'http://www.vimeo.com/siai/videos/page:2/sort:oldest',
'http://www.vimeo.com/siai/videos/page:3/sort:oldest']
pages.each do |page|
doc = Nokogiri::html(open(page))
doc.search('//*[@href]').each do |m|
video_id = m[:href]
if video_id.match(/^\/(\d+)$/i)
links_set[video_id[/\d+/]] = m.children[0].to_s.split(" at ")[0].split(" -- ")[0]
end
end
end
links = links_set.to_a
p links
cookie = ''
file_name = ''
open("http://www.tubeminator.com") |f|
cookie = f.meta['set-cookie'].split(';')[0]
links.each do |link|
open("http://www.tubeminator.com/ajax.php?function=downloadvideo&url=http%3A%2F%2Fwww.vimeo.com%2F" + link[0],
"Cookie" => cookie) |f|
puts f.read
open("http://www.tubeminator.com/ajax.php?function=convertvideo&start=0&duration=1120&size=0&format=mp3&vq=high&aq=high",
"Cookie" => cookie) |f|
file_name = f.read
puts file_name
Net::HTTP.start("www.tubeminator.com") |http|
#http.read_timeout = 3600 # 1 hour
resp = http.get("/download-video-" + file_name)
open(link[1] + ".mp3", "wb") |file|
file.write(resp.body)
end
puts "\n Yay!!"
这是个例外:
/Users/test/.rvm/rubies/ruby-1.9.2-preview1/lib/ruby/1.9.1/net/protocol.rb:140:in `rescue in rbuf_fill': Timeout::Error (Timeout::Error)
from /Users/test/.rvm/rubies/ruby-1.9.2-preview1/lib/ruby/1.9.1/net/protocol.rb:134:in `rbuf_fill'
from /Users/test/.rvm/rubies/ruby-1.9.2-preview1/lib/ruby/1.9.1/net/protocol.rb:116:in `readuntil'
from /Users/test/.rvm/rubies/ruby-1.9.2-preview1/lib/ruby/1.9.1/net/protocol.rb:126:in `readline'
from /Users/test/.rvm/rubies/ruby-1.9.2-preview1/lib/ruby/1.9.1/net/http.rb:2138:in `read_status_line'
from /Users/test/.rvm/rubies/ruby-1.9.2-preview1/lib/ruby/1.9.1/net/http.rb:2127:in `read_new'
from /Users/test/.rvm/rubies/ruby-1.9.2-preview1/lib/ruby/1.9.1/net/http.rb:1120:in `transport_request'
from /Users/test/.rvm/rubies/ruby-1.9.2-preview1/lib/ruby/1.9.1/net/http.rb:1106:in `request'
from /Users/test/.rvm/rubies/ruby-1.9.2-preview1/lib/ruby/1.9.1/open-uri.rb:312:in `block in open_http'
from /Users/test/.rvm/rubies/ruby-1.9.2-preview1/lib/ruby/1.9.1/net/http.rb:564:in `start'
from /Users/test/.rvm/rubies/ruby-1.9.2-preview1/lib/ruby/1.9.1/open-uri.rb:306:in `open_http'
from /Users/test/.rvm/rubies/ruby-1.9.2-preview1/lib/ruby/1.9.1/open-uri.rb:767:in `buffer_open'
from /Users/test/.rvm/rubies/ruby-1.9.2-preview1/lib/ruby/1.9.1/open-uri.rb:203:in `block in open_loop'
from /Users/test/.rvm/rubies/ruby-1.9.2-preview1/lib/ruby/1.9.1/open-uri.rb:201:in `catch'
from /Users/test/.rvm/rubies/ruby-1.9.2-preview1/lib/ruby/1.9.1/open-uri.rb:201:in `open_loop'
from /Users/test/.rvm/rubies/ruby-1.9.2-preview1/lib/ruby/1.9.1/open-uri.rb:146:in `open_uri'
from /Users/test/.rvm/rubies/ruby-1.9.2-preview1/lib/ruby/1.9.1/open-uri.rb:669:in `open'
from /Users/test/.rvm/rubies/ruby-1.9.2-preview1/lib/ruby/1.9.1/open-uri.rb:33:in `open'
from test.rb:38:in `block in <main>'
from test.rb:37:in `each'
from test.rb:37:in `<main>'
我也很感谢您对其余代码的 cmets。
【问题讨论】:
可能是您在构建视频下载的 url 时出了点问题。选择有问题的网址并尝试手动下载。 嗨 Lucas :) URL 没问题,我可以用浏览器下载文件。问题是在下载较大的文件(大约 20MB)时超时。 【参考方案1】:对于 Ruby 1.8,我用它来解决我的超时问题。在我的代码中扩展 Net::HTTP 类并使用默认参数重新初始化,包括我自己的 read_timeout
的初始化,我认为应该保持理智。
require 'net/http'
# Lengthen timeout in Net::HTTP
module Net
class HTTP
alias old_initialize initialize
def initialize(*args)
old_initialize(*args)
@read_timeout = 5*60 # 5 minutes
end
end
end
【讨论】:
谢谢你,在我需要你的那一刻,你就像从天而降的天使。 @Darren 很高兴我能帮上忙 :-) 尼克,您可以将此代码放在应用程序层次结构中的任何位置,只要它保存的文件在运行时加载/需要。 @RansomAni-Gizzle,你为什么这样做而不是像我在这里那样说http = Net::HTTP.new(uri.host, uri.port); http.open_timeout = 5* 60; http.read_timeout = 5* 60
***.com/questions/14314375/…
@Grienders 因为我需要将解决方案模块化并只实例化一次。您的解决方案也可以,但是如果您在另一个文件中使用变量 http 而不使其成为全局变量,则必须重做 "Net::HTTP.new(uri.host, uri.port); http.open_timeout = 5* 60 ; http.read_timeout = 5* 60" 一遍又一遍地在不同的文件中,而你可以把它放在一个重要的地方。我会觉得那很乱……我猜只是个人喜好。 :-)【参考方案2】:
您的超时不在您设置超时的代码中。在这里,你可以使用 open-uri:
open("http://www.tubeminator.com/ajax.php?function=downloadvideo&url=http%3A%2F%2Fwww.vimeo.com%2F" + link[0],
您可以像这样为 open-uri 设置读取超时:
#!/usr/bin/ruby1.9
require 'open-uri'
open('http://***.com', 'r', :read_timeout=>0.01) do |http|
http.read
end
# => /usr/lib/ruby/1.9.0/net/protocol.rb:135:in `sysread': \
# => execution expired (Timeout::Error)
# => ...
# => from /tmp/foo.rb:5:in `<main>'
:read_timeout
是 Ruby 1.9 的新功能(不在 Ruby 1.8 中)。 0 或 nil 表示“没有超时”。
【讨论】:
你知道 Ruby 1.8 的解决方案吗? @madh,我不知道,但可以使用例如 wget。 可以设置Net::HTTP对象的read_timeout和conn_timeout。 替代方案:使用路边。 curb.rubyforge.org API 很奇怪,但它没有任何 Net::HTTP 超时问题(仅适用于 Ruby 1.8.x)。 工作就像一个魅力。感谢您的帮助!以上是关于Ruby Net::HTTP 超时的主要内容,如果未能解决你的问题,请参考以下文章