2011-09-21 17 views
12

Tôi có một nhiệm vụ cào mà lấy về dữ liệu JSON từ một API, phân tích nó, và lưu nó vào cơ sở dữ liệu:Lỗi 404 với mở-uri trong một công việc cào ... những gì gây ra nó?

task :embedly => :environment do 
    require 'json' 
    require 'uri' 
    require 'open-uri' 

    Video.all.each do |video| 
    json_stream = open("http://api.embed.ly/1/oembed?key=08b652e6b3ea11e0ae3f4040d3dc5c07&url=#{video.video_url}&maxwidth=525") 
    ruby_hash = JSON.parse(json_stream.read) 
    thumbnail_url = ruby_hash['thumbnail_url'] 
    embed_code = ruby_hash['html'] 
    video.update_attributes(:thumbnail_url => thumbnail_url, :embed_code => embed_code) 
    end 
end 

tôi nhận được lỗi này trong ngăn xếp dấu vết khi tôi chạy nhiệm vụ cào và tôi không có ý tưởng điều gì gây ra nó:

rake aborted! 
404 Not Found 
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:277:in `open_http' 
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:616:in `buffer_open' 
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:164:in `open_loop' 
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:162:in `catch' 
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:162:in `open_loop' 
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:132:in `open_uri' 
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:518:in `open' 
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:30:in `open' 
/rubyprograms/dreamstill/lib/tasks/tasks.rake:16 
/rubyprograms/dreamstill/lib/tasks/tasks.rake:15:in `each' 
/rubyprograms/dreamstill/lib/tasks/tasks.rake:15 
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:636:in `call' 
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:636:in `execute' 
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:631:in `each' 
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:631:in `execute' 
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:597:in `invoke_with_call_chain' 
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/monitor.rb:242:in `synchronize' 

Bất kỳ ý tưởng nào về sự cố và cách giải quyết?

Trả lời

20

Embed.ly api trả về 404 nếu tài nguyên được chỉ định (video/hình ảnh) không tồn tại. OpenURI xử lý điều này như một ngoại lệ. Để bắt lỗi, bạn có thể làm điều gì đó như sau:

task :embedly => :environment do 
    require 'json' 
    require 'uri' 
    require 'open-uri' 

    Video.all.each do |video| 
    begin 
     json_stream = open("http://api.embed.ly/1/oembed?key=08b652e6b3ea11e0ae3f4040d3dc5c07&url=#{video.video_url}&maxwidth=525") 
     ruby_hash = JSON.parse(json_stream.read) 
     thumbnail_url = ruby_hash['thumbnail_url'] 
     embed_code = ruby_hash['html'] 
     video.update_attributes(:thumbnail_url => thumbnail_url, :embed_code => embed_code) 
    rescue OpenURI::HTTPError => ex 
     puts "Handle missing video here" 
    end 
    end 
end 

Bạn cũng có thể kiểm tra xem video/url có hợp lệ không trước khi chạy tác vụ.

+0

bất kỳ ý tưởng về làm thế nào tôi có thể in ra các url đó là 404? – lulalala

1

Bạn không URL mã hóa của bạn video.url:

json_stream = open("...url=#{video.video_url}...") 

vì vậy bạn có thể tạo ra một URL đọc sai và api.embed.ly đang nói với bạn rằng nó không thể tìm thấy nó. Ví dụ: nếu video.video_urlhttp://a.b?c=d&e=f thì e=f sẽ được xem như một tham số cho http://api.embed.ly/1/oembed thay vì được chuyển đến thông qua http://a.b.

Bạn có thể muốn làm điều này thay vì:

require 'cgi' 
#... 
json_stream = open("...url=#{CGI.escape(video.video_url)}...") 
Các vấn đề liên quan