work.log

元エンジニアの備忘録的ブログ

PerlのWebページスクレイピング覚書 (Web::Scraper 編)

投稿:

Perl で Web ページをスクレイピングするメモ書きです。

これまでずーっと HTML::TreeBuilder を使ってスクレイピングしてたのですが、そう言えば Web::Scraper ってのもあったけど試してなかったなとふと思い出しました。

関連記事
PerlのWebページスクレイピング覚書

目的は「スクレイピング」なので HTML::TreeBuilder でも事足りるのは確かですが、物によっては結構複雑になりがちだったので Web::Scraper はどんなもんよと試してみました。

Web::Scraper のサンプルコード

前回と同様に自分のブロクからタイトルを抜き出すようなコードを Web::Scraper で書いてみます。

#!/usr/bin/perl

use strict;
use warnings;
use Web::Scraper;
use URI;
use Encode;

    my $enc = find_encoding 'utf8';
    my $uri = new URI('https://worklog.be/');

    my $scraper = scraper {
        process '#content h1', 'title[]' => 'TEXT';
    };

    my $res = $scraper->scrape($uri);

    foreach (@{$res->{title}}) {
        print $enc->encode($_) . "\n";
    }

exit;

こんな感じに非常にシンプルに書けました。

実行結果はこんな感じです。

# perl scraper.pl

TwentyTwelveでカスタム投稿タイプ用のテンプレートを準備する
Googlebot が JSONP を取得しようとしてきた件
Haproxy 運用の思いつきメモ
Googlebotのjavascriptインデックス検証の結果と次のテスト
TwentyTwelveにカスタム投稿タイプを付けて記事を分けてみる
WordPressのマルチサイト機能を試してみる
Googlebotがjavascriptの実行結果をインデックスするか検証する
Google Analyticsのクリックカウント用スクリプトを改良した
TwentyTwelveでカテゴリ連動型のタグ検索フォームを作成する
WordPressでカテゴリに関連付いたタグ一覧を取得する

ここまでなら HTML::TreeBuilder でもそんなに変わらないのですが、Web::Scraper は別条件のデータも同時にスクレイピングできる優れ物。

※ HTML::TreeBuilder でも勿論できるけど場合によってはネストしまくった処理になってちょっと面倒臭い。

例えば、ブログタイトルとアンカーテキストの href 属性も一緒に抜き出すならこんな感じに。

#!/usr/bin/perl

use strict;
use warnings;
use Web::Scraper;
use URI;
use Encode;

    my $enc = find_encoding 'utf8';
    my $uri = new URI('https://worklog.be/');

    my $scraper = scraper {
        process 'h1.site-title', 'blog' => 'TEXT';
        process '#content h1', 'title[]' => 'TEXT';
        process '#content h1 a', 'href[]' => '@href';
    };

    my $res = $scraper->scrape($uri);

    print $enc->encode($res->{blog}) . "\n";

    for (my $i = 0; $i <= $#{$res->{title}}; $i++) {
        print "@{$res->{href}}[$i] = " . $enc->encode(@{$res->{title}}[$i]) . "\n";

    }

exit;

実行結果はこんな感じ。

# perl scraper.pl

work.log
https://worklog.be/archives/2740 = TwentyTwelveでカスタム投稿タイプ用のテンプレートを準備する
https://worklog.be/archives/2732 = Googlebot が JSONP を取得しようとしてきた件
https://worklog.be/archives/2728 = Haproxy 運用の思いつきメモ
https://worklog.be/archives/2717 = Googlebotのjavascriptインデックス検証の結果と次のテスト
https://worklog.be/archives/2714 = TwentyTwelveにカスタム投稿タイプを付けて記事を分けてみる
https://worklog.be/archives/2701 = WordPressのマルチサイト機能を試してみる
https://worklog.be/archives/2695 = Googlebotがjavascriptの実行結果をインデックスするか検証する
https://worklog.be/archives/2692 = Google Analyticsのクリックカウント用スクリプトを改良した
https://worklog.be/archives/2682 = TwentyTwelveでカテゴリ連動型のタグ検索フォームを作成する
https://worklog.be/archives/2680 = WordPressでカテゴリに関連付いたタグ一覧を取得する

便利すぎて感激です。

Web::Scraper は、「process ‘対象’, ‘ハッシュキー’ => ‘取り出すデータ’」みたいに書いたら後はよろしくどうぞーという感じなのですっごく簡単でシンプルに書けます。

HTML::TreeBuilder で書いたコードを全部移植しないとな…

簡単ですが Web::Scraper のメモは以上になります。