NDO::WeblogのnaoyaさんがMonday Module ひとり - HTML::LinkExtorというエントリでMonday Moduleの予行演習をやってらっしゃったので、言い出しっぺは僕だし、やはり面白いとは思うので僕もスクリプト作ってみました。
HTML::LinkExtorということで、HTMLからURLを抜き出すものなわけですが、単にURLリストではやはり面白くないですね。かなり考えて(嘘、10分くらい)、個人的にこんなのがあったら面白いかもと思い、Tower Recordsから検索してサンプル提供されているWindows Mediaのプレイリストを作成するスクリプトにしました。お題のHTML::LinkExtorを2回使ってます。
#!/usr/local/bin/perl
# Monday Module: HTML::LinkExtor
#
# 引数に与えた文字列でTowerRecords.comを検索し、その結果からWindows
# Mediaで提供されているサウンドクリップを更に探して、Windows Media
# Playlistとして出力する
#
# Kyo Nagashima <kyo@hail2u.net>
# 2003/11/20 作成
use strict;
use HTML::LinkExtor;
use LWP::Simple;
# 引数を取得してURLエンコード
my $query = shift;
$query =~ s!([^a-zA-Z0-9_.-])!uc sprintf "%%%02x", ord($1)!eg;
# 検索
my $content = LWP::Simple::get("http://www.towerrecords.com/Music/Default.aspx?search_in=music&free_text=$query");
# HTMLソースから検索結果の一覧のところまでを削除
$content =~ s!^.*?Sort items by!!is;
# リンク抽出
my @urls;
my $p = HTML::LinkExtor->new(\&callback, "http://www.towerrecords.com/music/");
sub callback {
my($tag, %links) = @_;
if ($tag eq "a") {
push(@urls, values %links);
}
}
$p->parse($content);
# CDのURLだけにする(callbackでやれよ)
my @cds;
foreach (@urls) {
if (m!^http://www\.towerrecords\.com/product\.aspx\?pfid=!) {
push(@cds, $_);
}
}
# 重複URLを削除
my %count;
@cds = grep(!$count{$_}++, @cds);
my @wms;
foreach my $cd (@cds) {
# CDのURLを取得
$content = LWP::Simple::get($cd);
@urls = ();
$p->parse($content);
# Windows MediaのURLだけにする
foreach (@urls) {
if (m!^http://mfile\.akamai\.com/.*?\.asx\?obj=!) {
push(@wms, $_);
}
}
}
# Windows Mediaがなかったら終了
if (!@wms) {
exit;
}
# Windows Media Playlistを出力(再生できるからこれで良さげ)
print <<"_WPL_";
<?wpl version="1.0"?>
<smil>
<body>
<seq>
_WPL_
foreach my $wm (@wms) {
$wm =~ s!&!&!;
print qq! <media src="$wm"/>\n!;
}
print <<"_WPL_";
</seq>
</body>
</smil>
_WPL_
exit;
標準出力に出てくるファイルはこんな感じ。
<?wpl version="1.0"?>
<smil>
<body>
<seq>
<media src="http://mfile.akamai.com/3171/wm2/muze.download.akamai.com/2890/us/uswm2/454/488454_1_07.asx?obj=v30729&urlid=b67557aff4096b9abd"/>
</seq>
</body>
</smil>
これをWindows Media Player 9で開いてやれば、ずらーっと再生できます。サンプルのサウンド・クリップなので短いのが難点。リンクを取得する時にHTMLをパースしてタイトルとかを取ってきて各asxファイルのタイトルにしたり、asxのURLからもう一回、LWP::Simple::getしてWindwos MediaそのもののURLを拾って来たり、もっと綺麗なプレイリストになりますが、メンドイので。再生できさえすればいいですしね。
こんな感じの軽い感じでやると良いかもしれないっすね。なんでMonday Moduleなのかというのはnaoyaさんが言ってるように、語呂が良いからだけです。
さて、本当にこの企画は始まるのでしょうか!!!