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!
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/')
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')
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.
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
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.