6

Perl の LWP を使用してWeb スクレイピングを行っています。URL のセットを処理する必要があり、そのうちのいくつかは (1 回以上) リダイレクトされる可能性があります。

HEAD メソッドを使用して、すべてのリダイレクトが解決された最終的な URL を取得するにはどうすればよいですか?

4

2 に答える 2

12

フル機能バージョンのLWP::UserAgentを使用する場合、返される応答はHTTP :: Responseのインスタンスであり、 HTTP::Requestが属性として含まれます。これは、応答インスタンス内の要求インスタンスを取得するメソッドのHTTP :: Responseドキュメントで説明されているように、URLのセットに元のURLを使用して作成したHTTP::Requestと必ずしも同じではないことに注意してください。

$ r-> request($ request)

これは、リクエスト属性を取得/設定するために使用されます。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で述べられているように、デフォルトではGETおよびHEADリクエストのリダイレクトに従います:

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

...
       キーのデフォルト
       ----------- --------------------
       max_redirect 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 恒久的に移動 (1 秒)
** ヘッド http://www.unur.com/ ==> 200 OK
http://www.unur.com/
于 2010-03-18T14:41:22.050 に答える