読者です 読者をやめる 読者になる 読者になる

[perl] Class::Method::Modifiers で WWW::Mechanize の送信するリクエスト内容をロギング

WWW::Mechanize がどんなリクエストを送っているのか、をログに出力してデバッグに使いたいという話。

Class::Method::Modifiers を使って、LWP::UserAgent::send_request を hook してあげるとうまくいった。(WWW::Mechanize は LWP::UserAgent の子クラス)

use strict;
use WWW::Mechanize;
use Class::Method::Modifiers;
use Data::Dumper;
use utf8;
$Data::Dumper::Indent = 1;

before "LWP::UserAgent::send_request" => sub {
    print Dumper $_[1];
};

my $mech = WWW::Mechanize->new;
$mech->get("http://d.hatena.ne.jp/sfujiwara/");
$mech->follow_link( text_regex => qr/記事一覧/ );

実行結果

$VAR1 = bless( {
  '_content' => '',
  '_uri' => bless( do{\(my $o = 'http://d.hatena.ne.jp/sfujiwara/')}, 'URI::http' ),
  '_headers' => bless( {
    'user-agent' => 'WWW-Mechanize/1.68',
    'accept-encoding' => 'gzip'
  }, 'HTTP::Headers' ),
  '_method' => 'GET',
  '_uri_canonical' => $VAR1->{'_uri'}
}, 'HTTP::Request' );
$VAR1 = bless( {
  '_content' => '',
  '_uri' => bless( do{\(my $o = 'http://d.hatena.ne.jp/sfujiwara/archive')}, 'URI::http' ),
  '_headers' => bless( {
    'cookie2' => '$Version="1"',
    'user-agent' => 'WWW-Mechanize/1.68',
    'cookie' => 'b=$1$sYSZ0Uab$aQH2JllGPhieYdpLtYKo81',
    'accept-encoding' => 'gzip',
    'referer' => 'http://d.hatena.ne.jp/sfujiwara/'
  }, 'HTTP::Headers' ),
  '_method' => 'GET',
  '_uri_canonical' => $VAR1->{'_uri'}
}, 'HTTP::Request' );

[追記]

tomi-ru LWP::UserAgentそのものにもhookポイントついていたような。

というブクマコメントをいただいたので、perldoc をよく読んだらありました。add_handler で hook を追加することができます。

$mech->add_handler(
    request_send => sub {
        my ($request, $ua, $h) = @_;
        print Dumper $request;
        return;  # HTTP::Response を返すか、return; する必要がある
    }
);

これで、Class::Method::Modifiers を使ったのと同様の動作をします。