Hippo2000 (2000/7/28)
LWPモジュールのクックブックなのです。
作者はGisle Aasさんです。メールで許可をいただきました。
2001/6/21:山宮隆さんからの指摘を受けて、余分な「;」を削除しました。
2002/12/19 : 河野 武さんからの指摘を受けて余分な「;」を削除しました(COOKIEの例文)
2003/2/22:まこと@CPAN.jpさんからの指摘を(またまた(^^;)受けて、誤字を修正しました。
lwpcook - libwww-perl クックブック
このドキュメントには、ibwww-perlライブラリの典型的な使い方を示すいくつかのサンプルが入っています。詳細については各モジュールのドキュメントをご覧下さい。
すべてのサンプルは実行可能なプログラムのはずです。ほとんどの場合、プログラムテキストをperlに直接パイプすることによってコード部分をテストすることができます。
ネットからドキュメントを取り出すだけなら、このライブラリを使って簡単にできます。LWP::Simpleモジュールは、URL引数で指定されたドキュメントを返すget()関数を提供しています:
use LWP::Simple; $doc = get 'http://www.sn.no/libwww-perl/';
あるいは、getprint()関数を使ったperlワンライナーならば:
perl -MLWP::Simple -e 'getprint "http://www.sn.no/libwww-perl/";'
あるいは最新のperlをこのコマンドを実行して取り出すというのはいかがです?:
perl -MLWP::Simple -e '
getstore "ftp://ftp.sunet.se/pub/lang/perl/CPAN/src/latest.tar.gz";,
"perl.tar.gz"'
まずは以下のようなコマンドを実行することで、あなたに一番近いCPANサイトを見つけ出したいかもしれませんね:
perl -MLWP::Simple -e 'getprint "http://www.perl.com/perl/CPAN/CPAN.html";'
この簡単なもので十分!LWPオブジェクト指向インターフェースは、サーバへのリクエストをさらに制御できます。このインタフェースを使うと、ヘッダの送信や返されたレスポンスをどのように扱いたいかについてすべて制御することができます:
use LWP::UserAgent;
$ua = LWP::UserAgent->new;
$ua->agent("$0/0.1 " . $ua->agent);
# $ua->agent("Mozilla/8.0") # とても能力のあるブラウザようなふりをします
$req = HTTP::Request->new(GET => 'http://www.linpro.no/lwp');
$req->header('Accept' => 'text/html');
# リクエストの送信 $res = $ua->request($req);
# 出力のチェック
if ($res->is_success) {
print $res->content;
} else {
print "Error: " . $res->status_line . "\n";
}
ライブラリと一緒に配布されるlwp-requestプログラム(別名GET)も、WWWサーバからのドキュメント取り出しに使うことができます。
ドキュメントがあるか(つまりURLが正しいか)をチェックしたいだけであれば、以下のようなコードを実行してみてください:
use LWP::Simple;
if (head($url)) {
# ok ドキュメントは存在します
}
head()関数は本当にドキュメントのメタ情報のリストを返します。返されるリストの最初の3つの値はドキュメントのタイプ、ドキュメントの大きさ、ドキュメントの年齢(age)です。
リクエストをもっと制御したり、返された値のすべてのヘッダの値にアクセスするためには、上記のGETで説明したオブジェクト指向インターフェースをつかう必要があります。単に s/GET/HEAD/g. してください。
WWWにデータをポストするために、単純な手続き型のインターフェースはありません。これにはオブジェクト指向インタフェースを使わなければなりません。最も通常のPOST処理はWWWフォーム・アプリケーションにアクセスすることです:
use LWP::UserAgent; $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(POST => 'http://www.perl.com/cgi-bin/BugGlimpse');
$req->content_type('application/x-www-form-urlencoded');
$req->content('match=www&errors=0');
my $res = $ua->request($req); print $res->as_string;
怠惰な人たちは適切なPOSTリクエスト・メッセージを構築するためにHTTP::Request::Commonモジュールを使います(それはすべてのエスケープすることを扱い、そしてcontent_typeのために適切なデフォルトを持ちます):
use HTTP::Request::Common qw(POST); use LWP::UserAgent; $ua = LWP::UserAgent->new;
my $req = POST 'http://www.perl.com/cgi-bin/BugGlimpse',
[ search => 'www', errors => 0 ];
print $ua->request($req)->as_string;
ライブラリと一緒に配布されるllwp-request プログラム(別名POST)も、データのポストに使うことができます。
サイトによってはファイアーウォール機能やパフォーマンスを向上させるためのたんなるキャッシュを実現するためにプロキシーを使っています。libwww-perlライブラリによって直接サポートされない(あるいはうまくサポートされていない:-))プロトコルを通してリソースにアクセスするためにも,プロキシーを使うことができます。
リクエスト送信を開始する前に、プロキシー設定を初期化しなければなりません:
use LWP::UserAgent; $ua = LWP::UserAgent->new; $ua->env_proxy; # initialize from environment variables # or $ua->proxy(ftp => 'http://proxy.myorg.com'); $ua->proxy(wais => 'http://proxy.myorg.com'); $ua->no_proxy(qw(no se fi));
my $req = HTTP::Request->new(GET => 'wais://xxx.com/'); print $ua->request($req)->as_string;
LWP::Simple インターフェースはあなたに代わって自動的にenv_proxy()を呼びます。$ua->env_proxyメソッドを使うアプリケーションは、通常、$ua->proxy()と$ua->no_proxyメソッドは使いません。
プロキシーによっては、リクエストを通すためにユーザ名/パスワードを送信することも要求することがあります。以下のようにして、要求されるヘッダを追加することができます:
use LWP::UserAgent;
$ua = LWP::UserAgent->new; $ua->proxy(['http', 'ftp'] => 'http://proxy.myorg.com');
$req = HTTP::Request->new('GET',"http://www.perl.com";);
$req->proxy_authorization_basic("proxy_user", "proxy_password");
$res = $ua->request($req); print $res->content if $res->is_success;
proxy.myorg.com、proxy_userそしてproxy_paswordをあなたのサイトに合わせて置き換えてください。
基本認証によって保護されているドキュメントは以下のようにして簡単にアクセスできます:
use LWP::UserAgent;
$ua = LWP::UserAgent->new;
$req = HTTP::Request->new(GET => 'http://www.linpro.no/secret/');
$req->authorization_basic('aas', 'mypassword');
print $ua->request($req)->as_string;
他の方法としては、get_basic_credentials()メソッドをオーバーライドするLWP::UserAgentのサブクラスを提供することがあります。この例としてlwp-request プログラムを調べてみてください。
サイトによってはクッキーでゲームを楽しむことを好みます。デフォルトではLWPは、それが訪れたサーバから提供されるクッキーを無視します。クッキー・ジャー(cookie jar)を設定することで、それらを集め始めることができます。
use LWP::UserAgent; use HTTP::Cookies;
$ua = LWP::UserAgent->new;
$ua->cookie_jar(HTTP::Cookies->new(file => "lwpcookies.txt",
autosave => 1));
# and then send requests just as you used to do $res = $ua->request(HTTP::Request->new(GET => "http://www.yahoo.no")); print $res->status_line, "\n";
保存するようにクッキーを送信するサイトに訪れると、ファイルlwpcookies.txtが大きくなります。
https機能を持つURLはhttp機能を持つものと全く同じようにアクセスされます。それは適切にインストールされているLWPのためのSSLインタフェース・モジュールにより提供されます(詳細はlibwww-perlディストリビューションのなかにあるREADME.SSL ファイルをご覧下さい)。LWPのためのSSLインタフェースが利用できなければ、そのようなURLにアクセスすると、"501 Protocol scheme 'https' is not supported"エラーになります。
以下にSSLを使っているWWWページの取り出しと出力の例を示します:
use LWP::UserAgent;
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => 'https://www.helsinki.fi/');
my $res = $ua->request($req);
if ($res->is_success) {
print $res->as_string;
} else {
print "Failed: ", $res->status_line, "\n";
}
WWWサーバからドキュメントをミラーしたければ、定期的に以下のようなコードを実行してみてください:
use LWP::Simple;
%mirrors = (
'http://www.sn.no/' => 'sn.html',
'http://www.perl.com/' => 'perl.html',
'http://www.sn.no/libwww-perl/' => 'lwp.html',
'gopher://gopher.sn.no/' => 'gopher.html',
);
while (($url, $localfile) = each(%mirrors)) {
mirror($url, $localfile);
}
もしくはperlワンライナーとして:
perl -MLWP::Simple -e 'mirror("http://www.perl.com/";, "perl.html")';
更新されていなければ、ドキュメントは転送されません。
取り出したいドキュメントがメモリに入りきらないほど大きければ、2つの代替案があります。ドキュメント内容をファイルに書きこむようライブラリに指示することができます($ua->request()の2番目の引数はファイル名になります):
use LWP::UserAgent; $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET =>
'http://www.linpro.no/lwp/libwww-perl-5.46.tar.gz');
$res = $ua->request($req, "libwww-perl.tar.gz");
if ($res->is_success) {
print "ok\n";
}
else {
print $res->status_line, "\n";
}
あるいは、ドキュメントが届いたときに処理することができます($ua->request()の2番目の引数はコード・リファレンスになります):
use LWP::UserAgent; $ua = LWP::UserAgent->new; $URL = 'ftp://ftp.unit.no/pub/rfc/rfc-index.txt';
my $expected_length;
my $bytes_received = 0;
my $res =
$ua->request(HTTP::Request->new(GET => $URL),
sub {
my($chunk, $res) = @_;
$bytes_received += length($chunk);
unless (defined $expected_length) {
$expected_length = $res->content_length || 0;
}
if ($expected_length) {
printf STDERR "%d%% - ",
100 * $bytes_received / $expected_length;
}
print STDERR "$bytes_received bytes received\n";
# XXX チャンクそのもので何かしなければなりません
# print $chunk;
});
print $res->status_line, "\n";
(原文のまま)
Copyright 1996-2000, Gisle Aas
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
ご意見、ご質問はこちらの掲示板で受け付けています。
またメールは河馬屋(Nifty)にお願いします。