2010-02-09 3 views
15

İlk Ruby programımı yazmaya çalışıyorum ama sorun yaşıyorum. Kod, HTTP üzerinden 32 MP3 dosyasını indirmelidir. Aslında birkaç tane indirir, sonra zaman aşımı.Ruby Net :: HTTP zaman aşımı

Zaman aşımı süresi ayarlamayı denedim, ancak fark yaratmıyor. Windows altında kod çalıştırmak, Cygwin ve Mac OS X, aynı sonuca sahiptir.

Bu

kodudur:

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

Ve bu istisna değildir:

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

kod geri kalanı üzerinde yorumlarınızı da takdir ediyorum.

+0

Belki de video indirme için URL'yi oluştururken yanlış giden bir şeyler var. Sorunlu URL'yi seçin ve manuel olarak indirmeyi deneyin. – Lucas

+1

Merhaba Lucas :) URL Tamam, dosyayı bir tarayıcıyla indirebiliyorum. Sorun, daha büyük dosyaları indirirken zaman aşımlarıdır (yaklaşık 20MB). –

cevap

15

Zamanaşımınız, zaman aşımı için ayarladığınız kodda değil.

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

Sen açık uri şöyle bir okuma zaman aşımı ayarlayabilirsiniz: Size açık uri kullandığınız yere, burada

#!/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 Ruby 1.9 için yenidir (o Ruby 1.8 değil) . 0 veya nil "zaman aşımı yok" anlamına gelir.

+0

Bir Ruby 1.8 çözümü biliyor musunuz? – madh

+0

@madh, yok, ama biri, örneğin, wget için dışarı koyabilirsiniz. –

+4

Net :: HTTP nesnesinin read_timeout ve conn_timeout özelliklerini ayarlayabilirsiniz. –

20

Ruby 1.8 için Zaman aşımı sorunlarımı çözmek için bunu kullandım. Kodumda Net :: HTTP sınıfını genişletmek ve kendi read_timeout'umun başlatılması da dahil olmak üzere varsayılan parametrelerle yeniden başlatılan şeyleri sanırım aklıma almalıyım.

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

Teşekkür ederim, sana ihtiyacım olan anda cennetten gelen bir melek gibisin. – Darren

+0

@Darren, yardım edebileceğine sevindim :-) –

+0

Bu kodu nereye koydun? – Nick