2010-03-18 12 views
5

Estoy haciendo algo de web scraping usando Perl's LWP. Necesito procesar un conjunto de URL, algunas de las cuales pueden redireccionar (una o más veces).¿Cómo puedo obtener la URL definitiva sin buscar las páginas con Perl y LWP?

¿Cómo puedo obtener la última URL con todas las redirecciones resueltas, usando el método HEAD?

+0

Esta es una víctima de http://stackoverflow.com/questions/2010366/how-can- i-find-the-final-url-after-all-redirections-in-perl – Ether

Respuesta

8

Como se indica en perldoc LWP::UserAgent, el valor predeterminado es seguir redirecciones para GET y HEAD solicitudes:

$ua = LWP::UserAgent->new(%options) 

... 
     KEY      DEFAULT 
     -----------    -------------------- 
     max_redirect   7 
     ... 
     requests_redirectable ['GET', 'HEAD'] 

Aquí se muestra un ejemplo:

#!/usr/bin/perl 

use strict; use warnings; 
use LWP::UserAgent; 

my $ua = LWP::UserAgent->new(); 
$ua->show_progress(1); 

my $response = $ua->head('http://unur.com/'); 

if ($response->is_success) { 
    print $response->request->uri->as_string, "\n"; 
} 

Salida:

** HEAD http://unur.com/ ==> 301 Moved Permanently (1s) 
** HEAD http://www.unur.com/ ==> 200 OK 
http://www.unur.com/
+0

Absolutamente correcto, pero creo que OP deseaba saber cuáles eran realmente las URL una vez que se habían seguido todas las redirecciones. –

+0

@Tony Gracias por el aviso. No me di cuenta inmediatamente y publiqué un guión de muestra aparentemente después de que tu respuesta fue aceptada. –

+0

Oooh, no vi el método uri-> as_string que muestra la secuencia completa. Muy agradable. –

11

Si usas la versión completa de LWP::UserAgent, entonces la respuesta que se devuelve es una instancia de HTTP::Response que a su vez tiene como atributo un HTTP::Request. Tenga en cuenta que esto es NOT necesariamente el mismo HTTP :: Solicitud que creó con la URL original en su conjunto de URL, como se describe en la documentación HTTP :: Response para el método para recuperar la instancia de solicitud dentro de la instancia de respuesta:

$ r-> petición (petición $)

Esto se utiliza para obtener/establecer el atributo de la petición. El atributo de solicitud es una referencia a la solicitud que provocó esta respuesta. No tiene que ser la misma solicitud que se pasa al método $ ua-> request(), ya que puede haber habido redirecciones y reintentos de autorización en el medio.

Una vez que tenga el objeto de solicitud, puede usar el método uri para obtener el URI. Si se usaron redireccionamientos, el URI es el resultado de seguir la cadena de redireccionamientos.

Aquí es un script Perl, probado y verificado, que proporciona el esqueleto de lo que necesita:

#!/usr/bin/perl 

use strict; 
use warnings; 

use LWP::UserAgent; 

my $ua; # Instance of LWP::UserAgent 
my $req; # Instance of (original) request 
my $res; # Instance of HTTP::Response returned via request method 

$ua = LWP::UserAgent->new; 
$ua->agent("$0/0.1 " . $ua->agent); 

$req = HTTP::Request->new(HEAD => 'http://www.ecu.edu/wllc'); 
$req->header('Accept' => 'text/html'); 

$res = $ua->request($req); 

if ($res->is_success) { 
    # Using double method invocation, prob. want to do testing of 
    # whether res is defined. 
    # This is inline version of 
    # my $finalrequest = $res->request(); 
    # print "Final URL = " . $finalrequest->url() . "\n"; 
    print "Final URI = " . $res->request()->uri() . "\n"; 
} else { 
    print "Error: " . $res->status_line . "\n"; 
} 
+0

Gracias por la explicación detallada. – planetp

Cuestiones relacionadas