読者です 読者をやめる 読者になる 読者になる

ゆーすけべー日記

はてなBlogってどーなの!?

鎌団子にPerlを教える「スクレイピング編その1」

鎌団子が Perl を始めた。「初めてのPerl」を夜な夜な読んでから寝ているらしい。

昨日は久しぶりにオモロキオフィスに行って鎌団子と会ったので、 「じゃあ、お勉強もいいけど実際に Perl のコードを書こう」ということになった。 コードを書く前にどんなものを作りたいかが重要なんだけど、 いろいろ話していくと最初は Webページや Web API 等 から情報取得をしたらいいじゃないかとまとまった。

そこでとりあえず「ボケて」の自分のボケページから、ボケに対する星をつけてもらった数の合計(1ページ内にボケがいくつか表示されているのでそれの合計)を数えるプログラムを作ることにした(リンク: 鎌団子のボケページ)。 「それ、データベース持ってんだから直接読めばいいんじゃね」と思いつつ、スクレイピング、 つまり Web ページから情報を引っこ抜いてくる手法を試してみることにした。 ボケてのページを再確認したところ、Web::Scraper を使うほどあまり構造化されていないことに 気づいたので正規表現を使う方向でやってみる。

そんな具合で、サンプルコードを書いてみて解説をした。 自分でいきなり書くのはさすがに難しいし、時間もかかる。最終的には自分でモジュール探したり、もしくは自分で書いたりして作っていくべきなんだけど、いいきっかけになるかなぁと。 で、1行1行といってもそんな量ないんだけど、説明してみたらそこそこ納得してもらった様子である。

自分もまだ勉強中の身であるが、このくらいだったら教えられるんだなと思ったり、 Perl ってモジュールうまく使えばコード量かなり減らせるんだと気づいたり、個人的にも面白かった。

プログラミングはきっかけが大事なので、鎌団子だけじゃなくてこの日記を見てもらっている人にも、その機会になればすごく嬉しい。 ということで以下がサンプルコード、とコメントつきのサンプルコード。 鎌団子にPerlを教えるがシリーズ化するかもしれないということでとりあえずそれに対応できるタイトルにしてみたので、続きがあるかもねー。

コメント無し

use strict;
use warnings;
use Encode;
use LWP::UserAgent;
use Perl6::Say;
use utf8;

my $url     = "http://bokete.jp/user/kamadango/boke";
my $ua      = LWP::UserAgent->new;
my $res     = $ua->get($url);
my $content = $res->content;

$content = Encode::decode( "utf8", $content );
my @counts = $content =~ /★の合計.*?(\d+)/gm;

my $total = 0;
for my $count (@counts) {
    $total += $count;
}

say "total: $total";

コメントあり

use strict;
use warnings;

use Encode;
use LWP::UserAgent;
use Perl6::Say;
use utf8;

# ボケて kamadango ボケページ の URL
my $url = "http://bokete.jp/user/kamadango/boke";

# ページを取得するために LWP::UserAgent モジュールを使う、インスタンス化
my $ua = LWP::UserAgent->new;

# get メソッドを使ってレスポンス(HTTP::Response)のオブジェクトを取得する
my $res = $ua->get($url);

# 本来ならばここで取得が失敗した場合の処理を入れるが割愛
# HTTP::Response の content メソッドを使って取得したページの中身を変数に入れる
my $content = $res->content;

# 取得したページを utf8 で decode する
$content = Encode::decode( "utf8", $content );

# 正規表現を使って★の合計数を数字として持ってきて、配列に入れる
my @counts = $content =~ /★の合計.*?(\d+)/gm;

# 配列を for 文でまわして該当する要素の値を
# $count 変数に入れつつ、$total 変数へ足していく
my $total = 0;
for my $count (@counts) {
    $total += $count;
}

# say メソッドで標準出力へ書き出す
say "total: $total";

初めてのPerl
posted with yusukebe.com::AmazonSearch on 2009.1.20
  • ランダル・L. シュワルツ トム フェニックス
  • 単行本 / オライリージャパン
  • Amazon 売り上げランキング: 12066
  • Amazon おすすめ度の平均: 4.5
    • 5 素晴らしきPerlの世界への案内
    • 5 読み物としても十分面白い
    • 5 定番書
    • 5 初心者も持っておきたい一冊
    • 5 CGI言語としてのPerl
Amazon.co.jpで詳細を見る

モダンPerl入門
posted with yusukebe.com::AmazonSearch on 2009.1.20
  • 牧 大輔
  • 大型本 / 翔泳社
  • Amazon 売り上げランキング: 532
Amazon.co.jpで詳細を見る