WWW::Mechanize + Proxy 認証

某サイトからデータ引っ張ってくるためにWWW::MechanizeとWeb::Scraperでコーディングした。

Mech + Proxy認証でハマったところ。。。

clone
my $mech_clone = $mech->clone

上記でcloneを作成すると、Proxyの設定はしてくれない。

そのため、元々のオブジェクトにおいてproxyメソッドでproxyを設定した場合は、プロキシを利用しない。
また、環境変数を設定しておきnewでenv_proxyを呼ばせて自動設定させた場合は、proxy認証部分(http://foo:bar@proxyhost:proxyportのfoo:bar部分)にアクセスしようとする。

実際の動作としては、$mech->{handlers}->{request_preprepare}にLWP::UserAgent::Proxyオブジェクトが入らない。

これは、$mech->cloneではLWP::UserAgentのcloneメソッドを利用している(下記参照)のでLWPのバグor仕様っぽい。

use base 'LWP::UserAgent';

--snip--

sub clone {
    my $self  = shift;
    my $clone = $self->SUPER::clone();

    $clone->cookie_jar( $self->cookie_jar );

    return $clone;
}

cloneするのにいちいちproxyを設定しなおすのも嫌なのでmechがproxyを持っていたら再度設定するように書き直した。

こんな感じ。

sub mech_fixup {
    package WWW::Mechanize;
    no warnings 'redefine';
    *clone = sub {
        my $self  = shift;
        my $clone = $self->SUPER::clone();

        $clone->cookie_jar( $self->cookie_jar );

        if(exists $self->{proxy}){
            while(my ($k, $v) = each %{$self->{proxy}}){
                $clone->proxy([$k],$v);
            }
        }
        return $clone;
    }
}

Web::Scraperのドキュメント

Podが充実してないので若干使いにくい。
ぐぐれば山ほど出てくるし、ソース読めばいいとはいえPod充実させてほしいなぁ