2008年、Webは文字列解析で変わっていくまとめサイト2.0(3/8 ページ)

» 2007年12月28日 10時44分 公開
[大澤文孝,ITmedia]

WWW::Mechanizeによるコンテンツの取得

 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);

WWW::Mechanizeでリンクを辿る

 コンテンツを取得するだけならば、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.

注目のテーマ