2011-01-16

Yahoo! Japanのインターネットドリルの問題をダウンロードしてCSVファイル化するスクリプト

Yahoo! Japanの「学習」カテゴリには「インターネットドリル」という教材があります。このドリルの問題をダウンロードしてCSVファイルに保存するPerlスクリプトを作成しましたので、Gistに置いておきます。<https://gist.github.com/781581>

来週1月23日に英検準1級を受ける予定になっています。個人的には、資格試験に合格したところでほとんど役には立たないと思ってはいますが、合格に向けて勉強すること自体にはそれなりに意味があるかと思っています。

TOEICと比較して、準1級では語彙力が問われます。直接的なボキャブラリが必要な語彙問題もだいぶ難しいのですが、長文問題に出てくる単語が難しいのが地味に厳しいところです。前後の文脈である程度推測できることも多いのですが、何度読みなおしても意味が取れないこともしばしばあります。

そこで、前述のインターネットドリルにある英検向けのドリルをやってみようと思ったわけですが、ブラウザ上でいちいちクリックしながら解くのも面倒なので、例によってWeb::Scraperを使ってスクレイピングして、CSVファイルに保存するPerlスクリプトをでっち上げた次第です。

使い方ですが、例えば「英検準1級単熟語マスター3000 (vol.1~3)」をダウンロードする場合、以下のようにURLを引数に渡せばOKです。「yahoodrill_23004.csv」といった感じの名前でCSVファイルが生成されます。

perl makecsv_yahoodrill.pl "http://stepup.yahoo.co.jp/drill/drill.html?co=23&di=23004&gi=03"
perl makecsv_yahoodrill.pl "http://stepup.yahoo.co.jp/drill/drill.html?co=23&di=23005&gi=03"
perl makecsv_yahoodrill.pl "http://stepup.yahoo.co.jp/drill/drill.html?co=23&di=23006&gi=03"

それにしても、ちょっとした作業をこんな感じでサッとプログラムを書いて実現するというのは気持ちのいいものです。コンピュータによる自動化は素晴らしい。唯一の難点は、ダウンロードした3000問の問題を来週の英検までにやる暇があるのかどうかという点ですね。脳のメモリに単語をダウンロードするのも自動化したい……。

#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use WWW::Mechanize;
use Text::CSV_XS;
use Web::Scraper;
sub remap {
tr/\x{301c}\x{2212}/\x{ff5e}\x{ff0d}/;
return $_;
}
my $url = $ARGV[0];
die "Invalid URL" unless defined $url && $url =~ m{^http://stepup\.yahoo\.co\.jp/drill/drill\.html\?};
$url =~ /[\?&]di=([0-9]+)/;
my $di = $1;
my $mech = new WWW::Mechanize(autocheck => 0);
$mech->get($url);
die unless $mech->success();
my $scrap_tmp = scraper {
process '//div[@id="drilltop-entitle"]/h1/cite', 'title' => 'TEXT';
process '//div[@id="kiroku-watchwrap"]/ul/li/a[1]', 'href' => '@href';
}->scrape($mech->content, $mech->uri);
$mech->get($scrap_tmp->{href});
die unless $mech->success();
open my $file, '>:encoding(cp932)', "yahoodrill_${di}.csv" or die $!; # force output in CP932
print $file "$scrap_tmp->{title}\n";
my $scraper = scraper {
process '//div[@id="question-contents-area"]/div/p[1]', 'question' => ['TEXT', \&remap];
process '//div[@id="question-contents-area"]/div/ul[1]/li', 'choices[]' => ['TEXT', \&remap];
process '//dd[@id="kaito-correct"]', 'answer' => ['TEXT', \&remap];
process '//div[@id="answer-contents-area"]/p[@id="commentary-txt"]', 'description' => ['TEXT', \&remap];
};
my $csv = Text::CSV_XS->new({binary => 1});
for (my $number = 1;; $number++) {
sleep 1;
unless ($mech->follow_link(text => "問題No.$number", url_regex => qr/.*answer\.html.*/)) {
if ($mech->follow_link(text => "次へ", url_regex => qr/.*list\.html.*/)) {
next;
} else {
last;
}
}
print "Now scraping No.$number...\n";
my $scrap = $scraper->scrape($mech->content, $mech->uri);
$csv->combine($scrap->{question}, @{$scrap->{choices}}, $scrap->{answer}, $scrap->{description});
print $file $csv->string() . "\n";
$mech->back();
}
close $file;
=head1 NAME
makecsv_yahoodrill - A script to download "Yahoo! Japan Internet Drill" as a CSV file.
=head1 SYNOPSIS
makecsv_yahoodrill <URL>
=head1 EXAMPLES
makecsv_yahoodrill "http://stepup.yahoo.co.jp/drill/drill.html?co=23&di=23004&gi=03"
=head1 DESCRIPTION
このスクリプトを使って、Yahoo! Japanのインターネットドリル<L<http://stepup.yahoo.co.jp/drill/>>の問題をCSVファイルに書き出すことができます。
引数として指定するURLは、個々のドリルのトップページのURLを指定してください(「問題にチャレンジする」や「問題一覧を見る」のボタンがあるページです)。
=head1 AUTHOR
en45masao

0 件のコメント:

コメントを投稿