新しい研究室で本の整理をしたついでに、ISBN をコンピュータに入力した。 さて、これをどうやって書誌情報に変換するか。業者だとおっきなデータベースがあるのだろうけど、 一般人は直接さわることはできない。
ということでオンライン書店に頼ることにする。 さしあたり使いやすいのは amazon.co.jp である。和書も洋書も扱えるからである。 とはいえ古い本やマイナーな本などは引けないものもあるのだが、まあいいであろう。
ちうわけで perl の出番である。例によって例のごとくきたない正規表現で Amazon の吐く HTML から書誌情報を取り出している。 しかし、そのへんの本の番号を入力するだけでいろいろな情報がとれるのは面白い。
念のため、あんまり乱用する (可能な全 ISBN を試すとか……) のはやめてください。amazon の負荷があがります。というかほとんど DoS 攻撃になってしまう……。必要な分だけにしてあげてください。
#!/usr/local/bin/perl
# Amazon ripper 1.0
# by Makino Takaki
use Jcode;
use LWP::UserAgent;
use HTTP::Request::Common;
$ua = LWP::UserAgent->new;
print '"Input","Title","Subtitle","Authors","Booktype","Pages","Edition"' .
',"PubDate","Publisher","ISBN","size"' . "\n";
while(<>)
{
chop;
$response = $ua->request(GET "http://www.amazon.co.jp/exec/obidos/ASIN/$_");
sleep 1;
if( ! $response->is_success )
{
print "\"$_\",\"**** no data found ***\"\n";
next;
}
$str = new Jcode($response->content)->euc; # Windows 上なら sjis に
if( $str =~ /say-what-man.gif/ )
{
print "\"$_\",\"**** no data found ***\"\n"
}
else {
($title,$dummy,$dummy,$dummy,$subtitle,$authors) =
$str =~
/ <b><font face=[^<>]+>
(([^<>&]|&[^<>n])+) # 書名
(( )+([^<>]+))? # サブタイトル
<\/font><\/b><br>\n*
((<a\shref="\/exec\/obidos\/search-handle-url\/
[^"]+">[^<>]+<\/a>[^<>]*)+) # 著者列
/xis;
if( $title eq "" ) # 上の方式だと著者列が空のときには取得できない
{ # ページタイトルから書名だけでもゲットする
($title) = $str =~
/<title>[\s\n]*Amazon.co.jp:[^<>:]*:
\s*([^<>]+)<\/title>/xis;
}
($btype, $dummy, $pages, $dummy, $edition, $dummy,
$pubdate, $publisher, $isbn, $sizeunit, $size) =
$str =~
/
<b>([^<>]+)<\/b> # 本のタイプ (文庫とか)
\n+\s*
(-\s*([0-9]+)\s*p)? # ページ数
[\s\n]+
(\/\s*([^\s\n][^\n]*))? # Edition
[\s\n]+
(\(([^<>]+)\))? # 出版日
\n*<br>\n*<font [^<>]+>\n*
([^<>\n]+) # 出版社
[\n\s]+;[\n\s]*ISBN:\s*
([^<>\n\s]+) # ISBN
\s*;[\s\n]+サイズ\s*\(
([^<>\n\s]+) # サイズ単位 (常に cm?)
\):\s*
([^<>\n]+)? # サイズ情報
/xis;
$authors =~ s/<[^<>]+>//g;
print "\"$_\",\"$title\",\"$subtitle\",\"$authors\"," .
"\"$btype\",\"$pages\",\"$edition\",\"$pubdate\"," .
"\"$publisher\",\"$isbn\",\"$size($sizeunit)\"\n";
}
}