2010-02-09 24 views
15

Tôi đang cố gắng viết chương trình Ruby đầu tiên của mình, nhưng có một vấn đề. Mã phải tải xuống 32 tệp MP3 qua HTTP. Nó thực sự tải xuống một vài, sau đó lần ra.Ruby Net :: HTTP time out

Tôi đã thử đặt khoảng thời gian chờ nhưng không có sự khác biệt. Chạy mã trong Windows, Cygwin và Mac OS X có cùng kết quả.

Đây là mã:

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!!" 

Và đây là ngoại lệ:

/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>' 

Tôi cũng đánh giá cao ý kiến ​​của bạn trên phần còn lại của mã này.

+0

Có thể đã xảy ra sự cố khi bạn tạo url để tải xuống video. Chọn url có vấn đề và cố tải xuống theo cách thủ công. – Lucas

+1

Hi Lucas :) URL là OK, tôi có thể tải tệp xuống bằng trình duyệt. Vấn đề là nó hết thời gian chờ trong khi tải xuống các tệp lớn hơn (khoảng 20MB). –

Trả lời

15

Thời gian chờ của bạn không có trong mã bạn đặt thời gian chờ. Đó là ở đây, nơi bạn sử dụng mở uri:

open("http://www.tubeminator.com/ajax.php?function=downloadvideo&url=http%3A%2F%2Fwww.vimeo.com%2F" + link[0], 

Bạn có thể thiết lập một thời gian chờ đọc cho mở uri như vậy:

#!/usr/bin/ruby1.9 

require 'open-uri' 

open('http://stackoverflow.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 là mới cho Ruby 1.9 (nó không phải trong Ruby 1.8) . 0 hoặc nil có nghĩa là "không có thời gian chờ".

+0

Bạn có biết giải pháp Ruby 1.8 không? – madh

+0

@madh, tôi không, nhưng người ta có thể bóc vỏ, ví dụ, wget. –

+4

Bạn có thể đặt read_timeout và conn_timeout của đối tượng Net :: HTTP. –

20

Đối với Ruby 1.8 tôi đã sử dụng điều này để giải quyết các vấn đề về thời gian chờ của mình. Mở rộng Net :: HTTP lớp trong mã của tôi và tái khởi tạo với các thông số mặc định bao gồm một khởi tạo của riêng tôi read_timeout nên giữ những điều lành mạnh tôi nghĩ.

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 
+3

Cảm ơn bạn, bạn giống như một thiên thần đến từ thiên đàng ngay tại thời điểm tôi cần bạn. – Darren

+0

@ Darren vui vì tôi có thể trợ giúp :-) –

+0

Bạn đã đặt mã này ở đâu? – Nick

Các vấn đề liên quan