miauのブログ

はてなダイアリー「miauの避難所」をはてなブログに移行しました

パセラで曲検索

たまにカラオケに行くと、他の人が歌った曲で「いい曲だなー、あとでググろう」みたいなのが結構あります。

先日もカラオケに行ったんですが、普段なら気になった曲だけメモするところを、なぜか興に乗って全曲目を携帯でメモしてしまって。せっかくなので、そのメモを元に カラオケパセラ Σ-Search で検索を行うスクリプトを書いてみました。

携帯でのメモ

cagayake girls ふ・ほ
super nova ぴ
嘘 ふ
princess primp ほ
:(以下略)

こんな感じで、曲名+スペース+歌った人をメモしてました。右側は歌った人の頭文字ですね。

スクリプト

汚いけど載せておきます。

$KCODE = "UTF8"

# TODO:   の置換とか

require "nkf"
require "open-uri"
require "cgi"

# URL サンプル
#   http://pasela.jp/search/pc/search.php?ss=%89R&line=0&lim=30
# 検索後は Shift_JIS で指定。

$url_format = 'http://pasela.jp/search/pc/search.php?ss=%s&line=0&lim=%s'
columns = %w{No 歌った人 歌手名 タイトル 代表曲番号 歌い出し タイアップ ジャンル}

# 検索実行
def simple_get(song, count)
  url = sprintf $url_format, CGI.escape(conv_song(song)), count
  open(url){|f|
    return NKF.nkf('-wS -m0', f.read)
  }
end

# 歌名検索時に邪魔な記号をスペースに置換
def conv_song(song)
  return song.gsub(%r{[\x20-\x2f\x3a-\x40\x5b-\x5f\x7b-\x7e〜・(×)]}, ' ')
end

# 歌った人の略称をちゃんとしたものに変換
def conv_singer(singer)
  return singer.sub(//, 'ふがさん').
                sub(//, 'ほげさん').
                sub(//, 'ぴよさん')
end

puts columns.join("\t")
DATA.each_with_index {|line, i|
  _, song, singer = */(.*) (.*)/.match(line)
  
  content = simple_get(song, 30)
  
  if content.match(%r{検索データが見つかりませんでした})
    puts [ i+1, conv_singer(singer), song ].join("\t")
    next
  end
  
  count = content.slice(%r{検索結果:(\d+)}, 1)
  unless count
    puts "parse error at #{song}"
    print content
    break
  end
  
  if count.to_i > 30
    content = simple_get(song, count)
  end
  
  content.scan(%r{<TR><TD>([^>]*)</TD><TD>([^>]*)</TD><TD>([^>]*)</TD><TD>([^>]*)</TD><TD>([^>]*)</TD><TD>([^>]*)</TD></TR>}){|m|
    m.unshift [ i+1, conv_singer(singer) ]
    puts m.join("\t")
  }
  sleep(1)
}

__END__
cagayake girls ふ・ほ
super nova ぴ
嘘 ふ
princess primp ほ
:(以下略)

実際検索してみると、同じ曲名でもいろいろヒットするので、曲番号をメモしておけばよかったです・・・。

技術的なこと

もともと REXML で処理しようとしてたけど、パセラの検索結果ページが HTML なので REXML は使えないようで。HTML Tidy や HTML2XHTML とやらで valid XHTML に変換する方法もあるみたいだけど、どうも簡単じゃなさそうだったので、結局正規表現で適当に抽出しちゃいました。

その正規表現も、1.8 系だとちょっと貧弱な印象。練習がてら Ruby でやってみたけど、今度からこういう HTML を扱うときは、PerlPython で書こう。

以前からの疑問

こういう「当日歌った曲目を参照できるサービス」みたいなのってカラオケ屋で提供されてないんでしょうか?割増料金で提供する形でも、後で曲目を DL できるようにしてアフィ貼り付けておくでも、店側の利益になりそうなのでやればいいと思うんですけど。