Ruby-net / http-redirections suivantes

j'ai une URL et J'utilise HTTP GET pour transmettre une requête à une page. Que se passe - t-il avec la saveur la plus récente (en net/http) est que le script ne va pas au-delà de la réponse 302. J'ai essayé plusieurs solutions différentes: HTTPClient, net / http, Rest-Client, Patron...

j'ai besoin d'un moyen pour continuer à la page finale afin de valider une balise d'attribut sur ces pages html. La redirection est due à un agent utilisateur mobile qui frappe une page qui redirige vers une vue mobile, donc l'agent utilisateur mobile dans l'en-tête. Voici mon code tel qu'il est aujourd'hui:

require 'uri'
require 'net/http'

class Check_Get_Page

    def more_http
        url = URI.parse('my_url')
        req, data = Net::HTTP::Get.new(url.path, {
        'User-Agent' => 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5'
        })
        res = Net::HTTP.start(url.host, url.port) {|http|
        http.request(req)
            }
        cookie = res.response['set-cookie']
        puts 'Body = ' + res.body
        puts 'Message = ' + res.message
        puts 'Code = ' + res.code
        puts "Cookie n" + cookie
    end

end

m = Check_Get_Page.new
m.more_http

toute suggestion serait grandement appréciée!

34
demandé sur phs 2011-08-04 02:42:45

5 réponses

Pour suivre les redirections, vous pouvez faire quelque chose comme ceci ( Extrait de ruby-doc)

Suivant La Redirection

require 'net/http'
require 'uri'

def fetch(uri_str, limit = 10)
  # You should choose better exception.
  raise ArgumentError, 'HTTP redirect too deep' if limit == 0

  url = URI.parse(uri_str)
  req = Net::HTTP::Get.new(url.path, { 'User-Agent' => 'Mozilla/5.0 (etc...)' })
  response = Net::HTTP.start(url.host, url.port) { |http| http.request(req) }
  case response
  when Net::HTTPSuccess     then response
  when Net::HTTPRedirection then fetch(response['location'], limit - 1)
  else
    response.error!
  end
end

print fetch('http://www.ruby-lang.org/')
55
répondu emboss 2015-12-02 14:06:21

j'ai écrit un autre cours pour ceci basé sur des exemples donnés ici, merci beaucoup à tout le monde. J'ai ajouté des cookies, des paramètres et des exceptions et j'ai finalement obtenu ce dont j'avais besoin:https://gist.github.com/sekrett/7dd4177d6c87cf8265cd

require 'uri'
require 'net/http'
require 'openssl'

class UrlResolver
  def self.resolve(uri_str, agent = 'curl/7.43.0', max_attempts = 10, timeout = 10)
    attempts = 0
    cookie = nil

    until attempts >= max_attempts
      attempts += 1

      url = URI.parse(uri_str)
      http = Net::HTTP.new(url.host, url.port)
      http.open_timeout = timeout
      http.read_timeout = timeout
      path = url.path
      path = '/' if path == ''
      path += '?' + url.query unless url.query.nil?

      params = { 'User-Agent' => agent, 'Accept' => '*/*' }
      params['Cookie'] = cookie unless cookie.nil?
      request = Net::HTTP::Get.new(path, params)

      if url.instance_of?(URI::HTTPS)
        http.use_ssl = true
        http.verify_mode = OpenSSL::SSL::VERIFY_NONE
      end
      response = http.request(request)

      case response
        when Net::HTTPSuccess then
          break
        when Net::HTTPRedirection then
          location = response['Location']
          cookie = response['Set-Cookie']
          new_uri = URI.parse(location)
          uri_str = if new_uri.relative?
                      url + location
                    else
                      new_uri.to_s
                    end
        else
          raise 'Unexpected response: ' + response.inspect
      end

    end
    raise 'Too many http redirects' if attempts == max_attempts

    uri_str
    # response.body
  end
end

puts UrlResolver.resolve('http://www.ruby-lang.org')
5
répondu sekrett 2016-01-22 08:32:48

La référence qui a fonctionné pour moi est ici: http://shadow-file.blogspot.co.uk/2009/03/handling-http-redirection-in-ruby.html

comparé à la plupart des exemples (y compris la réponse acceptée ici), il est plus robuste car il gère des URLs qui ne sont qu'un domaine (http://example.com - doit ajouter un/), traite spécifiquement SSL, et aussi les URLs relatives.

bien sûr, vous seriez mieux d'utiliser une bibliothèque comme RESTClient dans la plupart des cas, mais il est parfois nécessaire d'avoir des détails de bas niveau.

3
répondu mahemoff 2014-04-18 13:38:27

Peut-être vous pouvez utiliser le trottoir fu gem ici https://github.com/gdi/curb-fu la seule chose, c'est certain code supplémentaire pour faire suivre la redirection. J'ai utilisé les éléments suivants avant de. Espérons que cela aide.

require 'rubygems'
require 'curb-fu'

module CurbFu
  class Request
    module Base
      def new_meth(url_params, query_params = {})
        curb = old_meth url_params, query_params
        curb.follow_location = true
        curb
      end

      alias :old_meth :build
      alias :build :new_meth
    end
  end
end

#this should follow the redirect because we instruct
#Curb.follow_location = true
print CurbFu.get('http://<your path>/').body
1
répondu Yesh 2011-08-04 02:24:26

donne une URL qui redirige

url = 'http://httpbin.org/redirect-to?url=http%3A%2F%2Fhttpbin.org%2Fredirect-to%3Furl%3Dhttp%3A%2F%2Fexample.org'

A. Net::HTTP

begin
  response = Net::HTTP.get_response(URI.parse(url))
  url = response['location']
end while response.is_a?(Net::HTTPRedirection)

assurez-vous de traiter le cas quand il y a trop de redirections.

B. OpenURI

open(url).read

OpenURI::OpenRead#open suit les redirections par défaut, mais ne limite pas le nombre de redirections.

1
répondu Panic 2018-06-28 09:37:42