6

我正在使用 Perl 的 LWP进行一些网络抓取。我需要处理一组 URL,其中一些可能会重定向(1 次或多次)。

如何使用 HEAD 方法获得解决所有重定向的最终 URL?

4

2 回答 2

12

如果您使用LWP::UserAgent的全功能版本,则返回的响应是HTTP::Response的实例,该实例又具有HTTP::Request作为属性。请注意,这不一定与您使用 URL 集中的原始 URL 创建的 HTTP::Request 相同,如 HTTP::Response 文档中所述,用于在响应实例中检索请求实例的方法:

$r->请求($请求)

这用于获取/设置请求属性。request 属性是对导致此响应的请求的引用。它不必与传递给 $ua->request() 方法的请求相同,因为其间可能有重定向和授权重试。

获得请求对象后,您可以使用 uri 方法获取 URI。如果使用了重定向,则 URI 是遵循重定向链的结果。

这是一个经过测试和验证的 Perl 脚本,它为您提供了所需内容的框架:

#!/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";
}
于 2010-03-18T15:02:30.737 回答
8

perldoc LWP::UserAgent中所述,默认情况下遵循重定向GETHEAD请求:

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

...
       键默认
       ------------ --------
       最大重定向 7
       ...
       requests_redirectable ['GET', 'HEAD']

这是一个例子:

#!/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";
}

输出:

** HEAD http://unur.com/ ==> 301 永久移动 (1s)
** HEAD http://www.unur.com/ ==> 200 OK
http://www.unur.com/
于 2010-03-18T14:41:22.050 回答