在rake任务中使用open-uri 404错误…导致它的原因是什么?

我有一个rake任务,从API获取JSON数据,解析它,并将其保存到数据库:

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 

当我运行rake任务时,我在堆栈跟踪中得到此错误,我不知道是什么导致它:

 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' 

关于问题的任何想法以及如何解决它?

如果指定的资源(video/图片)不存在,则embed.ly api返回404。 OpenURI将此作为例外处理。 要捕获错误,您可以执行以下操作:

 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 

您还可以在运行任务之前检查video/url是否有效。

您不是对您的video.url URL编码:

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

所以你可能会产生一个错位的URL, api.embed.ly告诉你它无法找到它。 例如,如果video.video_urlhttp://ab?c=d&e=f ,那么e=f将被视为http://api.embed.ly/1/oembed的参数,而不是传递给它到http://ab

您可能希望这样做:

 require 'cgi' #... json_stream = open("...url=#{CGI.escape(video.video_url)}...")