Monday Moduleふたり

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!&!&amp;!;
  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&amp;urlid=b67557aff4096b9abd"/>
    </seq>
  </body>
</smil>

これをWindows Media Player 9で開いてやれば、ずらーっと再生できます。サンプルのサウンド・クリップなので短いのが難点。リンクを取得する時にHTMLをパースしてタイトルとかを取ってきて各asxファイルのタイトルにしたり、asxのURLからもう一回、LWP::Simple::getしてWindwos MediaそのもののURLを拾って来たり、もっと綺麗なプレイリストになりますが、メンドイので。再生できさえすればいいですしね。

こんな感じの軽い感じでやると良いかもしれないっすね。なんでMonday Moduleなのかというのはnaoyaさんが言ってるように、語呂が良いからだけです。

さて、本当にこの企画は始まるのでしょうか!!!