簡単!たった13行のコードでHTML取得&解析をするPerlスクリプト

13行のコードで、Yahoo!Japanのトピックス一覧を取得する!

PerlでHTML取得・解析したいときはLWP::UserAgentとHTML::TreeBuilderというのを使うと簡単にできます。
LWP::UserAgentを使うと、Webページの取得ができます。
HTML::TreeBuilderを使うと、HTMLのDOM解析ができます。

この2つのモジュールを使って、Yahoo!Japanのトピックス一覧を取得してみましょう。
コメント行と空行を除くとたったの13行です。

use strict;
use warnings;
use LWP::UserAgent;
use HTML::TreeBuilder;

# urlを指定する
my $url = 'http://www.yahoo.co.jp';

# IE8のフリをする
my $user_agent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)";

# LWPを使ってサイトにアクセスし、HTMLの内容を取得する
my $ua = LWP::UserAgent->new('agent' => $user_agent);
my $res = $ua->get($url);
my $content = $res->content;

# HTML::TreeBuilderで解析する
my $tree = HTML::TreeBuilder->new;
$tree->parse($content);

# DOM操作してトピックの部分だけ抜き出す。
# <div id='topicsfb'><ul><li>....の部分を抽出する

my @items =  $tree->look_down('id', 'topicsfb')->find('li');
print $_->as_text."\n" for @items;                          

実行結果↓↓

$ perl get_parse.pl

岡田氏ら11閣僚の再任内定
都知事「菅新内閣は極左」
主力級の種牛5頭 感染シロ
鳥獣駆除の2人 撃たれて死亡写真
イスラエル 新たに支援船だ捕写真NEW
はやぶさ地球へ 異例の人気写真
エトオ「日本が最も危険」
看護師アイドル「採血が快感」写真
今日の話題(40件)
一覧
をを!超かんたん!!

解説

主にHTML::TreeBuilderを解説します。

parse
my $tree = HTML::TreeBuilder->new;
$tree->parse($content);
$contentには、HTMLを文字列として格納したものが入ります。
必ずしもLWPを使う必要はなく、ローカルファイルを読み込んだものでもOKです。
ここまではお約束なので覚えてしまいましょう。


find, look_down, as_text
my @items =  $tree->look_down('id', 'topicsfb')->find('li');
print $_->as_text."\n" for @items;
↑をわかりやすく書くとこう↓です。
my $elm  = $tree->look_down('id', 'topicsfb');
my  @list =  $elm->find('li');
for my $li (@list) {
    print $li->as_text."\n"
} 

$tree->look_down('id', 'topicsfb') 
「HTML文書中で、id属性がtopicsfbである要素を取得せよ」です。
JavaScriptのdocument.getElementByID('topicsfb') とほぼ同じものです。

$elm>find('li');
「その要素の中のli要素のリストを取得せよ」です。
JavaSciptのelement.getElementsByTagName('li')とほぼ同じものです。

$li->as_text 
「その要素に含まれるテキスト文字列を取得せよ」です。
JavaSciptのelement.innerTextとほぼ同じものです。


このlook_down, find, as_textという3つのメソッドだけ覚えればたいていのことはできます。
(実はHTML::Elementというオブジェクトのメソッドです)
公式ドキュメントを見ると他にもごちゃごちゃといっぱいメソッドがありますが、最初は覚える必要ありません(キッパリ)

メッソドチェーン (jQuery的なアレ)
look_down,find, as_textは任意のHTML要素に対して実行できます。
また、戻り値はHTML要素を返します。
つまり、jQueryのようにメソッドチェーンをつなげてDOM要素を探索していくことができるのです。

print $tree->look_down('id', 'spotlight_mainfb')->find('ul')->find('li')->as_text;

# 結果
「女編集者、松方弘子28歳独身」
・・・働きマン?

レンタルサーバでも動く

Web::Scraperというモダンなモジュールもあるようですが、HTML::TreeBuilderの方がインストールが簡単です。
(私が使っているXreaレンタルサーバではデフォルトで入っていました。)

参考になった記事

補足1

Webページを取得するだけなら1行でできます!
簡単!たった1行のコードでWebページを取得するPerlスクリプト - DQNEO起業日記

補足2

いろんな方が補足記事を書いてくださったので、ご紹介いたします。
ツッコミありがとうございます!

HTML::TreeBuilder のメソッドを覚えるには人生はみじかすぎる件について

Tatsuhiko Miyagawa の HTML::Selector::XPath をつかえば、 use HTML::Selector::XPath 'selector_to_xpath'; print selector_to_xpath('#topicsfb li'), "\n"; # => //*[@id='topicsfb']//li のように、簡単に CSS Selector から XPath を生成することができる。

知りませんでした!ありがとうございます。

[PHP]簡単!たった6行のコードで HTML取得&解析をするPHPスクリプト
PHPだと6行ですか!すごい!

[perl] たった*行のコードでHTML取得&解析をしたい場合はWeb::Scraperが便利
コードが短い!
ありがとうございます。
ただ、Web::Scraperは私のようなPerl初心者にはインストールが難しかったです。。

補足3

いろいろ試行錯誤してWeb::Scraperをインストールできたので記事を書いてみました。
誰かのお役に立てば幸いです。
カテゴリ: