研究用のデータセットに大量のbeneign softwareが必要になったので、Vectorから一気に落とそうと思った。
というわけでググってみたところ、数年前まではanonymous ftpがあったらしいのだが、今は使えないようなので、スクレイピングしてみることにした。
neta@neta__
@takamuko_k @s4kura_4m4ne 一筋縄には行かなさそうなのでMechanizeでスクレイピングしてリンクたどっていくPerl/Rubyスクリプト書いてみては
2012/12/03 15:47:20
このアドバイスをもとにれっつ☆スクレイピング in Perlです
(成果物はhttps://github.com/t-chov/vectorScraperに置いてあります)
※WWW::MechanizeとWeb::Scraperを要求します
まずは最初のコード。超ダサい
#/usr/bin/perl
use utf8;
use WWW::Mechanize;
use Web::Scraper;
use Encode;
use URI;
use YAML;
binmode(STDOUT, ':encoding(utf8)');
# Mechanizeを設定
$mech = WWW::Mechanize->new(autocheck => 1);
$mech->agent_alias('Mac Safari');
# windows NT用のソフトウェア一覧を開く
$returnMainURI = 'http://www.vector.co.jp/vpack/filearea/winnt/';
$mech->get($returnMainURI);
# 大カテゴリ
@bigCategory = ("文書作成", "インターネット&通信", "ユーティリティ",
"画像&サウンド", "ビジネス", "パーソナル", "家庭&趣味",
"学習&教育", "ゲーム", "アミューズメント", "プログラミング",
"ハードウェア");
for($count = 0; $counrt < @bigCategory; $count++){
system("mkdir ./category$count");
# メインカテゴリのページを開く
$mech->follow_link(text => $bigCategory[$count]);
# サブカテゴリの設定
$scraper = scraper {
process 'h3 a', 'url[]' => '@href';
result 'url';
};
$res = $scraper->scrape($mech->content);
foreach $category(@{$res}){
if($category =~ /font\/$/){
next;
}
print "$category\n";
# サブカテゴリのページに遷移
$categoryURI = "http://www.vector.co.jp/".$category;
$mech->get($categoryURI);
# ファイル一覧を獲得
@fileAddr = $mech->content =~ /\/soft\/winnt\/[a-z]+\/se[0-9]{6}\.html/g;
foreach $downloadURI(@fileAddr){
# ファイル名を設定
@tmp = split(/\//, $downloadURI);
@tmp = split(/\./, $tmp[4]);
$downFileName = $tmp[0];
# ダウンロード
$mech->follow_link(url => $downloadURI);
$mech->follow_link(text => "ダウンロード");
if($mech->content =~ /\/download\/file\/winnt/){
$mech->follow_link(url_regex => qr/\/download\/file\/winnt/);
$mech->get($mech->uri());
$mech->follow_link("text"=> "こちらをクリックしてください");
# ファイルを保存
$directory = "category".$count."/".$downFileName;
print "\t$downFileName\n";
open OUTFILE,'>', $directory or die 'ERROR';
binmode OUTFILE;
print OUTFILE $mech->content;
close OUTFILE;
}
# 元のサブカテゴリURLに戻る
$mech->get($categoryURI);
}
$mech->get($returnMainURI);
}
}
print "\n";
use Strictしてない時点で論外なのだが、当然メモリ食い尽くして落ちる。
一番苦労したのがファイルの保存で、ページを踏むと自動で落ちてくるタイプのページな上に直接リンクを叩くとリファラで弾かれるため$mech->get($url, ":content_file"=>$filename)が使えない。
follow_linkには:content_fileがないから……とここで詰まる。
結局、「ダウンロードが始まらない時はこちら」を踏むと$mech->contentにファイルのバイナリが格納されるので、これをバイナリモードで書き込むことに。
ここが一番メモリを食うので、$mechをきちんと解放してあげればいいだろう、ということで書いたのが完成版。こいつはgithubにあるので、使いたい人はどうぞ。
ちなみにautocheckを外しているのだけど、これはautocheck入れると死んでるページでエラー吐いて落ちるから。むしろ死んでるページを生かしてるVectorさんサイドに問題があると思うのだけどw








