Perl - LWP
概要
libwww-perl。Perl 用の WWW ライブラリモジュール群。
HTTP プロトコルだけではなく、HTTPS や FTP、Gopher、NNTP などを介したリクエスト、あるいはローカルファイルや CPAN のファイルへのアクセス、sendmail によるメールの送信などが行える。
HTTPS プロトコルを利用する場合は、Crypt::SSLeay がインストールされていることが必要。
インストール
root ユーザで cpan -i LWP
とすると必要なモジュールも自動でインストールされる。Windows の ActivePerl には入ってるのか分からない。ppm install LWP
とかやるとインストールできるかも。
LWP の簡単な例
use LWP; print LWP::UserAgent->new->request( HTTP::Request->new(GET => "http://localhost/"))->content;
正直なところ、ただ HTTP サーバのファイルへアクセスする目的で HTTP::Request でリクエストオブジェクトを作ってから LWP::UserAgent オブジェクトに request させる、なんてのは少し面倒。そのために、より簡素なアクセスを行いたい場合に、単純化されたモジュールが用意されている。
LWP::Simple
その名の通り、シンプルな LWP のインターフェイス。内部では LWP を使っている。LWP::Simple によってデフォルトでエクスポートされるサブルーチンは以下の通り。
- get($url)
- $url へ GET によってアクセスし、その内容を返す。Not Found などで失敗すると undef が返される。$url は URL を示す文字列か URI オブジェクトのどちらか。
- head($url)
- $url へ HEAD によってアクセスし、サーバが返すヘッダを Content-Type, Content-Length, Modified, Expires, Server の順のリストとして返す。それ以外は GET と同じ。
- getprint($url)
- $url へ GET によってアクセスし、その内容をデフォルトの出力先に設定されているファイルハンドルへ出力する。失敗すると、ステータスコードとエラー内容が標準エラー出力へ出力される。返り値はサーバが返すレスポンスコード。
- getstore($url, $file)
- $url へ GET によってアクセスし、その内容を $file へ保存する。返り値はサーバが返すレスポンスコード。
- mirror($url, $file)
- getstore とほぼ同様だが、If-Modified-Since と Content-Length ヘッダを用いて内容に変化があるかを調べ、変化があれば新しく保存される。
デフォルトで LWP::Simple を使う(use LWP::Simple;
)場合、HTTP::Status のレスポンスコード(RC_*)を示す定数やそれがリクエストに成功したかを判断する is_seccess() と is_failure() もエクスポートされる。
また同様にデフォルトで LWP::Simple を使う場合には、get() はその内部で LWP::UserAgent を使用せず、IO::Socket::INET を使用してアクセスを行っている。たぶんそっちの方が処理が軽くて済むからに違いない。またその場合は、User-Agent として "lwp-trivial/*" が送られる。その他のサブルーチンは "LWP::Simple/*" として送られる。
LWP::UserAgent は LWP::Simple のモジュール内のグローバル変数 $ua として用いられている。この変数は、LWP::Simple を use する時に use LWP::Simple qw($ua get head);
などとして自分のパッケージへインポートして弄くることもできる。例えば、$ua->agent("hogehoge/0.2");
などとすると、送られる User-Agent を変更することができたり。また $ua をインポートすると、get が LWP::UserAgent を使うようになる。
LWP::UserAgent を使う
単純なアクセスを行う場合は LWP::Simple でいいのかも知れないけれど、ヘッダを解析したり POST を使いたい場合は LWP::Simple では力不足。それで、やっぱり LWP::UserAgent やらを使うということになる。
LWP::Simple を使わずとも、LWP::UserAgent では少し単純なアクセスを行うメソッド(get, head, post)が提供されている。POST アクセスもでき、さらにヘッダやフォームも送れるので、LWP::Simple よりは使い勝手がいい。
その例の一部
エラーなどは一切考慮していない例。実際に厳密さが要求される環境で使う場合は、ちゃんと返り値をチェックする必要がある。
get( URL [, ヘッダのキー => ヘッダの値 ]... )
GET リクエストを行う。HTTP::Response オブジェクトを返す。
use LWP; my $ua = LWP::UserAgent->new; my $res = $ua->get( "http://localhost/", "User-Agent" => "myUA/0.1", "X-Hoge" => "hoge" ); print $res->as_string; # サーバからの返答を、ヘッダも含めて文字列として得る print $res->content; # コンテントボディ # あるいは # print LWP::UserAgent->new->get( # "http://localhost/", # "User-Agent" => "myUA/0.1", # "X-Hoge" => "hoge" # )->as_string;
head( URL [, ヘッダのキー => ヘッダの値 ]... )
HEAD リクエストを行う以外は get と同様。
use LWP; my $ua = LWP::UserAgent->new; my $res = $ua->get( "http://localhost/", "User-Agent" => "myUA/0.1", "X-Hoge" => "hoge" ); print $res->content;
post()
- post( URL [[, { フォームのキー => フォームの値 }] [, ヘッダのキー => ヘッダの値 ]... ] )
- post( URL , ヘッダのキー => ヘッダの値 ]... [, Content => リクエストボディ )
POST リクエストを行う。
use LWP; my $ua = LWP::UserAgent->new; my $res = $ua->post( "http://localhost/", { "form_x" => "aaaaa", "form_y" => "にほんご" # 非アスキー文字はそれぞれ URL エンコードされる }, "User-Agent" => "myUA/0.1", "X-Hoge" => "hoge", "Content-Type" => "application/x-www-form-urlencoded" ); print $res->content;
フォームの値を渡す場合、"Content-Type" や "Content-Length" のヘッダは LWP::UserAgent オブジェクトが HTTP::Request::Common を利用して自動的に設定されて送られるため、こちら側がそれらのヘッダを渡す必要はない。
"Content-Type" がデフォルト値の "application/x-www-form-urlencoded" 以外の値として送る必要があれば、こちらで "Content-Type" ヘッダを設定するとともに、リクエストボディデータを Content の値として post() に渡す必要がある。例えば、エンコード形式(フォームの enctype 属性)が "multipart/form-data" としてされている場合など。
my $ua = LWP::UserAgent->new; my $res = $ua->post( "http://localhost/", Content => "hoge=33&hoge=11" ); # 滅多に使わないが、同名のキーを持つフォームのリクエストを行う場合
ただし "multipart/form-data" を送る場合は、post() メソッドを使ってリクエストを行うよりも、HTTP::Request::Common オブジェクトを直接扱って LWP::UserAgent へ request() させた方がいいかも知れない。boundary だのファイル名だの若干複雑なので……。
HTTP::Response オブジェクト
LWP::UserAgent オブジェクトの request() によって返るはずのオブジェクト。サーバからの応答内容が含まれている。HTTP::Response は HTTP::Message を継承しているため、それ由来のメソッドを持つ。以下はほんの一例。
my $res = $ua->get("http://localhost/"); # レスポンスコード (200, 301, 404, 500...) print $res->code; # ステータスメッセージ (OK, Moved Permanently, Not Found, Internal Server Error) print $res->message; # 特定のヘッダを得る(case-insensitive) print $res->header("Date"); # ヘッダを HTTP::Headers オブジェクトとして得る my $hs = $res->headers; print $hs->as_string; # 全てのヘッダフィールドの名前を得る my @names = $res->header_field_names; # Content-Type を得る print $res->content_type; # コンテントボディ(内容)を得る my $c = $res->content;
その他
LWP はクッキーを扱ったり、SSL によるアクセス、プロクシを介したアクセスを行ったりもできます。perldoc lwpcook
すると色々な情報が得られます。
リンク
Last modified:2009/12/02 14:04:35
0.075369