Ruby - how to download a file if the url is a redi

2019-07-06 08:42发布

问题:

Ruby how to download a file if the url is a redirection?

i'm trying to download this url:

soundcloud.com/stereo-f---/cohete-amigo/download

the redirection is this:

[ec-media.soundcloud.com/HNIGsuMJlDhy?ff61182e3c2ecefa438cd0210ad0e38569b9775ddc9e06b3c362a686319250ea5c1ae2d33d8d525807641f258e33de3cb0e559c1b591b5b00fb32d5ef9&AWSAccessKeyId=AKIAJ4IAZE5EOI7PA7VQ&Expires=1352919869&Signature=OVWD9VdV7ew%2B%2Fs%2BO0YpkKZLGOCw%3D][2]

and what i've tried is this:

Net::HTTP.start("ec-media.soundcloud.com") { |http|
  resp = http.get("/HNIGsuMJlDhy?ff61182e3c2ecefa438cd0210ad0e38569b9775ddc9e06b3c362a686319250ea5c1ae2d33d8d525807641f258e33de3cb0e559c1b591b5b00fb32d5ef9&AWSAccessKeyId=AKIAJ4IAZE5EOI7PA7VQ&Expires=1352919869&Signature=OVWD9VdV7ew%2B%2Fs%2BO0YpkKZLGOCw%3D")
  open("test.wav", "wb") { |file|
    file.write(resp.body)
  }
}
puts "Done."
sleep 50

i don't understand/know ANY of internet protocols and redirections and that things... please can give me a good explanation or help with my script to download files from soundcloud with ruby?

thankyou

UPDATE:

I've tried this way but i get an error:

Net::HTTP.start("soundcloud.com") do |http|
  resp = http.get("/dubstep-4/kill-paris-tender-love/download")

  while resp.code == '301' || resp.code == '302'
    # moved permanently or temporarily:  try again at the new location.
    resp = http.get(URI.parse(resp.header['location']))
    # ideally you should also bail if you make too many redirects.
  end

  # make sure the request was successful.
  if resp.code == '200'  
    open("test.wav", "wb"){ |file| file.write(resp.body) }
  else
    puts "Error: HTTP #{resp.code}"
  end
end

Error:

C:/Program Files (x86)/Ruby/lib/ruby/1.9.1/net/http.rb:1860:in `initialize': undefined method `empty?' for #<URI::HTTP:0x25a9ce8> (NoMethodError)
        from C:/Program Files (x86)/Ruby/lib/ruby/1.9.1/net/http.rb:2093:in `initialize'
        from C:/Program Files (x86)/Ruby/lib/ruby/1.9.1/net/http.rb:1026:in `new'
        from C:/Program Files (x86)/Ruby/lib/ruby/1.9.1/net/http.rb:1026:in `get'
        from C:/Users/Administrador/Desktop/1.rb:59:in `block in <main>'
        from C:/Program Files (x86)/Ruby/lib/ruby/1.9.1/net/http.rb:745:in `start'
        from C:/Program Files (x86)/Ruby/lib/ruby/1.9.1/net/http.rb:557:in `start'
        from C:/Users/Administrador/Desktop/1.rb:48:in `<main>'

回答1:

There is a standard library called Open URI that is higher level than Net HTTP. It follows redirects automatically:

require 'open-uri'
file = open("http://soundcloud.com/stereo-f---/cohete-amigo/download")


回答2:

What you need to do is look at resp.code and handle the redirect:

Net::HTTP.start("your.web.site") do |http|
  resp = http.get("/something")
  while resp.code == '301' || resp.code == '302'
    # moved permanently or temporarily:  try again at the new location.
    resp = http.get(URI.parse(resp.header['location']))
    # ideally you should also bail if you make too many redirects.
  end

  # make sure the request was successful.
  if resp.code == '200'  
    open("test.wav", "wb"){ |file| file.write(resp.body) }
  else
    puts "Error: HTTP #{resp.code}"
  end
end


回答3:

I'd suggest you see this guide here but the gist is you have to check the type of the response and then extract the URL from the body in the case of a redirection.

Now, SoundCloud probably has zaniness going on in the background with cookies and temporary URLs and such, but that's another problem to deal with.