WWW::Mechanizeは、第2週目で説明したLWP::UserAgentモジュールのサブクラスとして構成されている。
そのためLWP::UserAgentモジュールのすべてのメソッドを利用できる。つまり、getメソッドの引数に取得したいURLを設定すると、そのURLのコンテンツを取得できる。
use WWW::Mechanize;
my $url = 'http://blogs.itmedia.co.jp/';
my $mech = WWW::Mechanize->new();
$mech->get($url);
取得が成功したかどうかは、successメソッドで調べることができる。また取得したコンテンツがHTMLであるかどうかは、is_htmlメソッドで調査できる。
if ($mech->success() && $mech->is_html())
{
// 成功でありHTMLコンテンツである
}
実際のHTMLコンテンツは、contentメソッドで取得できる。このcontentメソッドは、どのような文字コードで書かれているのか分からない。
本連載では、ここまでEncode::Guessを使って自動判定をしてきたが、「自動巡回」という面では、さまざまなコンテンツが混じるということから、「Content-Typeヘッダ」を見てエンコードしたほうがよいだろう。そのコード記述は次のようになる。
use HTTP::Response::Encoding;
# 内容を取得
my $content = $mech->content();
# レスポンスを取得
my $res = $mech->response();
# 文字コード変換
# 1. Content-Typeから判定
my @encoding = (
$res->encoding,
($res->header('Content-Type')
=~ /charset=(\w\-]+)/g));
my $enc;
foreach my $value (@encoding)
{
if (Encode::find_encoding($value))
{
# 定義されているものが見つかった
$enc = $value;
last;
}
}
# 2. 見つからない場合は自動判定
if (!defined $enc)
{
Encode::Guess->setsuspects(
qw/shift-jis euc-jp 7bit-jis/);
$enc = "Guess";
}
$content = Encode::decode($enc, $content);
# たとえば先頭500文字を表示
print substr($content, 0, 500);
コンテンツを取得するだけならば、LWP::UserAgentモジュールを使うのと何ら変わらない。
WWW::Mechanizeの特徴は、コンテンツ中に埋め込まれたリンクやHTMLフィールドを操作して、リンク先をたどったり、フォームをサブミットできたりする点にある。今回は自動巡回が目的なのでフォームのサブミットについては省略し、リンクをたどる方法についてのみ説明する。
リンク先をたどるためのメソッドは、幾つか用意されているが、代表的なのは、find_all_linksメソッドだ。find_all_linksメソッドは括弧内に条件を指定すると、その条件に合致するリンクを示すWWW::Mechanize::Linkオブジェクトを返す。
次のようにforeachでループすれば、コンテンツに含まれる、それぞれのリンクを取り出せる。
foreach my $link ($mech->find_all_links(条件))
{
# ここで$linkがリンクを指すオブジェクト
}
条件には、表1のようなオプションが利用できる。例えば、
$mech->find_all_links(
url_abs_regex
=> qr#^http://blogs.itmedia.co.jp/#)
とすれば、URLが「http://blogs.itmedia.co.jp/」からはじまるリンクだけを取り出せるのだ。
表1■find_all_linksのオプション
オプション | 意味 |
---|---|
text | リンク文字に特定文字列と合致する |
text_regex | リンク文字が特定の正規表現とマッチする |
url | 記載されているURL(相対リンクと絶対リンクのどちらの場合もありうる)が特定の文字列と合致する |
url_regex | 記載されているURL(相対リンクと絶対リンクのどちらの場合もあり得る)が特定の正規表現とマッチする |
url_abs | 記載されているURLを絶対リンクに変換したものが特定の文字列と合致する |
url_abs_regex | 記載されているURLを絶対リンクに変換したものが特定の文字列と合致する |
name | name属性の値が特定文字列と合致する |
name_regex | name属性の値が特定の正規表現とマッチする |
id | id属性の値が特定文字列と合致する |
id_regex | id属性の値が特定の正規表現とマッチする |
class | class属性の値が特定文字列と合致する |
class_regex | class属性の値が特定の正規表現とマッチする |
tag | リンクのタグ(例えば「a」や「area」「frame」)を指定する |
tag_regex | リンクのタグ(例えば「a」や「area」「frame」)を正規表現で指定する |
WWW::Mechanize::Linkオブジェクトのurlメソッドは、リンクのURLを示す。リンク先をたどるには、このURLに対してgetメソッドを呼び出せばよい。
$mech->get($link->url());
リンク先をたどった後には、backメソッドを呼び出すことで、元のコンテンツに戻ることもできる。
$mech->back();
Webを巡回していくには、再帰呼び出しを使ってそれぞれのリンクをたどって行けばよい。実際に、再帰呼び出しを使って、Webを巡回する例を次ページのリスト1に示す。
なお、リスト1を実際に試すときには、再帰するレベルに注意しよう。再帰的にコンテンツをたどれば、対象となるサイトにかなりの負荷をかけることになるためだ。
Copyright © ITmedia, Inc. All Rights Reserved.