Kentaro Kuribayashi's blog

Software Engineering, Management, Books, and Daily Journal.

HTTP::Recorder による WWW::Mechanize ひな形コード生成

UNIX USER 2005 年 1 月号」の「UNIX 処方箋」にて「WWW::Mechanize モジュールによる Web アクセスの自動化」というコラムがあったので読んでみたら、WWW::Mechanize なコードを生成してくれる HTTP::Recorder なるモジュールが紹介されていて、これは便利げ! と思い、ちと使ってみた。

てか、Perl.com に "Web Testing with HTTP::Recorder" つって詳細な解説がありますね。

HTTP::Recorder は、HTTP::Proxy によるプロクシサーバの user agent として使用するもので、ブラウザでそのプロクシを経由してあちこちうろうろするだけで、WWW::Mechanize によるコードのひな形を生成してくれるというものです。詳細についてはドキュメントを参照してもらうことにして(こればっかりだな…)、とりあえず以下のようなコードを書いてプロクシサーバとして動作させ、ブラウザの設定でプロクシを設定後、うろうろしてみます。

#!/usr/bin/env perl

use strict;
use HTTP::Proxy;
use HTTP::Recorder;

# ログを記録するファイル
my $rec_file = './rec.txt';
# プロクシのポート
my $port = '8080';
# プロクシサーバのアドレス
my $host = '192.168.xxx.xxx';

my $proxy = HTTP::Proxy->new(
    port => $port,
    host => $host,
);
my $recorder = HTTP::Recorder->new;

$recorder->showwindow(0);
$recorder->file($rec_file);

$proxy->agent($recorder);
$proxy->start;

おもむろにあちこちをうろうろした後、ログファイルを見てみると、なにやらコードの断片が記録されているのを見ることができると思います。

…と、これだけじゃアレなんで、せっかくだから(謎)ってんで、ひとつモジュールをでっちあげることにします。

長ったらしい URL を短縮してくれるサービスがいろいろあるわけですが、日本語のサービスとしてはたとえば QRL.jp というサービスがあります。また、CPAN にはその手の URL 短縮サービスへのインタフェイスを提供する WWW::Shorten なるモジュール集があります。そこで、この WWW::Shorten の下位クラスのひとつとして、WWW::Shorten::QRL というモジュールを作成します。

まずは上記の手順により作成したプロクシを通して、QRL.jp により適当な短縮 URL を作成します。とりあえず、このブログの URL を短縮してみました。トップページを取得、フォームに URL を入力、送信、という手順を経ると、以下のようなコード片が生成されます。

$agent->get("http://qrl.jp/");

$agent->get("http://qrl.jp/favicon.ico");
$agent->form_name("form1");
$agent->field("o_url", "http://antipop.zapto.org/mt/");
$agent->submit_form(form_name => "form1");

$agent->get("http://qrl.jp/favicon.ico");

いかにもな感じのコード片が生成されました。これを元にモジュールを作成します。また、「この程度のコードなら、わざわざ HTTP::Recorder 使うよりも素で手書きする方が速いだろ。馬鹿ですか?」というツッコミはナシの方向でお願いいたします。泣きますよ?

というわけで、まずは favicon.ico を読みこんでしまってるところを削除します。その後、以下略な過程を経てできあがったのが、以下のコードです。激しく省略しまくっていますが、いちいち述べることもないほどのことだということなので、察してください。

package WWW::Shorten::QRL;

use strict;
use warnings;

use base qw( WWW::Shorten::generic Exporter );

our @EXPORT = qw( makeashorterlink makealongerlink );
our $VERSION = '0.01';

use Carp;
use WWW::Mechanize;

sub makeashorterlink {
	my $url = shift
		or croak 'No URL passed to makeashorterlink';
	my $ua = WWW::Mechanize->new;
	   $ua->get("http://qrl.jp/");
	   $ua->form_name("form1");
	   $ua->field("o_url", $url);
	   $ua->submit_form(form_name => "form1");
	return $1
		if $ua->response()->content() =~ m|(http://qrl\.jp/\?\d+)|;
	return undef;
}

sub makealongerlink {
	my $tinyurl_url = shift
		or croak 'No TinyURL key / URL passed to makealongerlink';
	my $ua = __PACKAGE__->ua();
	$tinyurl_url = "http://qrl.jp/?$tinyurl_url"
		unless $tinyurl_url =~ m|^http://|i;
	my $resp = $ua->get($tinyurl_url);
	return undef unless $resp->is_redirect;
	my $url = $resp->header('Location');
	return $url;
}

1;

というか、練習をかねてディストリビューションを作成してみましたので、公開してみます。

以下のように使用します。

use WWW::Shorten::QRL;

# 短縮 URL を生成する
my $short_url = makeashorterlink($long_url);
# 短縮 URL の元 URL を取得する
my $long_url  = makealongerlink($short_url);

つーかまぁ、こんなのマジどうでもいいや。ははは。

というわけで、いい例を示すことができなくてアレなのですが、HTTP::Recorder を用いると簡単に WWW::Mechanize なコードを作成することができるわけで、たとえば複数の画面を遷移するフォームのテストを作成したりする際等に用いると便利だったりするんじゃないかなぁとか思います。おしまし。