2011-04-03 7 views

Respuesta

1

Tendría que seguir la redirección. Creo que ayudaría:

http://shadow-file.blogspot.com/2009/03/handling-http-redirection-in-ruby.html

+1

No es técnicamente correcto. No es necesario que "siga" el redireccionamiento, solo necesita leer el encabezado de la ubicación que se envió para causar el redireccionamiento, como en la respuesta de Mladen Jablanović. – jemminger

+0

tiene razón, no dije eso correctamente :) – Spyros

+1

Es posible redirigir una redirección. A menos que el código subyacente maneje eso automáticamente, que no usará Net :: HTTP, los redireccionamientos deben seguirse también hasta que decida que las redirecciones son demasiado profundas, o finalmente se resuelven en la URL final. La página particular vinculada a es más intrincada que el ejemplo en Net :: HTTP's docs. –

23
require 'net/http' 
require 'uri' 

Net::HTTP.get_response(URI.parse('http://t.co/yjgxz5Y'))['location'] 
# => "http://nickstraffictricks.com/4856_how-to-rank-1-in-google/" 
+2

De acuerdo con los documentos, Net :: HTTP no realiza redireccionamientos recursivos, lo cual es necesario si se redirecciona un redireccionamiento. Parece que solo manejaría el primero. –

+1

Es cierto. Necesitarías un lazo alrededor de eso. Pero de todos modos, así es como seguirías una redirección en Ruby, y creo que eso responde la pregunta. –

8

He usado open-uri para esto, porque es agradable y sencilla. Se recuperará la página, pero también seguirá múltiples redirecciones:

require 'open-uri' 

final_uri = '' 
open('http://t.co/yjgxz5Y') do |h| 
    final_uri = h.base_uri 
end 
final_uri # => #<URI::HTTP:0x00000100851050 URL:http://nickstraffictricks.com/4856_how-to-rank-1-in-google/> 

Los documentos muestran un buen ejemplo para usar el menor nivel Net::HTTP para manejar las redirecciones.

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 

    response = Net::HTTP.get_response(URI.parse(uri_str)) 
    case response 
    when Net::HTTPSuccess  then response 
    when Net::HTTPRedirection then fetch(response['location'], limit - 1) 
    else 
    response.error! 
    end 
end 

puts fetch('http://www.ruby-lang.org') 

Por supuesto, todo esto se rompe si la página no utiliza una redirección HTTP. Muchos sitios usan meta-redirects, que debe manejar recuperando la URL de la metaetiqueta, pero esa es una pregunta diferente.

+0

Gracias! muy útil ... haciendo h.base_uri.to_s renderizará url de destino. – KG2289

+0

Creo que puede omitir el uso de bloque y simplemente llame a 'open (url) .base_uri' – lulalala

+0

La versión' Net :: HTTP' debe ser la respuesta aceptada, ya que maneja SSL así como redirecciones recursivas (la mayoría de los ejemplos parecen solo manejar uno u otro). ¡Bien hecho! –

3

Para resolver redirecciones, debe usar una solicitud HEAD para evitar descargar todo el cuerpo de la respuesta (imagine resolver una URL a un archivo de audio o video).

Ejemplo de trabajo utilizando la gema de Faraday:

require 'faraday' 
require 'faraday_middleware' 

def resolve_redirects(url) 
    response = fetch_response(url, method: :head) 
    if response 
     return response.to_hash[:url].to_s 
    else 
     return nil 
    end 
end 

def fetch_response(url, method: :get) 
    conn = Faraday.new do |b| 
     b.use FaradayMiddleware::FollowRedirects; 
     b.adapter :net_http 
    end 
    return conn.send method, url 
rescue Faraday::Error, Faraday::Error::ConnectionFailed => e 
    return nil 
end 

puts resolve_redirects("http://cre.fm/feed/m4a") # http://feeds.feedburner.com/cre-podcast 
Cuestiones relacionadas