コマンドラインでがんばるよ

ゲンナリする噂話も聞こえるけど無くなっちゃうものは仕方がない。その前に、“idolm@ster” タグが付いている動画を全部ぶっこ抜いてみようじゃねぇか!という思いつきから始めた試みの記録。
こういうのは思いつくところまではともかく、そっから先は往々にして別に内容云々じゃなく手段が目的化してしまい、道具を作ることそのものが楽しくてしょうがなくなっちゃう人だから困る。

> i=0;while [ $i -lt 145 ]; do w3m -dump_source http://www.stage6.com/videos/tag:idolm@ster?page=$i | egrep '\/user\/.*\/video\/' >> vidlink ; i=`expr $i + 1`; done


まずはこう。コマンドラインに直で打ってるから一行だけど、見難いので整形すると

#!/bin/bash

i=0
while [ $i -lt 145 ];
do
 w3m -dump_source http://www.stage6.com/videos/tag:idolm@ster?page=$i | egrep '\/user\/.*\/video\/' >> vidlink;
 i=`expr $i + 1`;
done


こうなる。今はもう見られないけど、idolm@sterタグの打たれた動画は144ページに渡っていたので、その全ての HTML からビデオへのリンク周辺を抜いてくる部分。
そうして抜いたリンクを整形するために Ruby スクリプトに喰わす。

> ruby -F'><' -ane “\$F.each do |tmp| if tmp.match(/^a href.*title.*/) then tmp.split(/'/)[1].split('/').each do |tmp2| print tmp2 if tmp2.match(/^[0-9]{7}\$/); end; print \“\t\“ + tmp.split(/'/)[3] + \“\n\“; end; end;“ vidlink > videodata


こいつも一行では何の事やらわからないが、ruby 部分はこんな処理を実行する。

#!/usr/bin/ruby

while gets
 $_.split('><').each do |tmp|
  if tmp.match(/^a href.*title.*/) then
   tmp.split(/'/)[1].split('/').each do |tmp2|
    print tmp2 if tmp2.match(/^[0-9]{7}$/)
   end
   print “\t“ + tmp.split(/'/)[3] + “\n“
  end
 end
end


動画のIDとタイトルを抜き出してタブ区切りのテキストにする。動画のIDは単純にURL中にある/で囲まれた7桁の数列をとっただけ。/^[0-9]{7]$/という正規表現で探しているのがそれだ。こうやって作ったデータファイルから

> cat videodata | ruby -F'\t' -ane “system('wget', '-O' + \$F[1].chomp() +'.divx', 'http://video.stage6.com/' + \$F[0] + '/.divx') unless File.exist?(\$F[1].chomp() +'.divx')“


のようにして ruby に喰わせる。これは整形の必要もないだろう。-e オプションの引数をダブルクォートでくくっているので、文字「$」を「\(バックスラッシュ)」でエスケープさせている以外は素直な一行スクリプト。ファイルの有無を判定して無ければ指定のタイトルとビデオのIDを元に wget を呼んでダウンロードする。上のワンライナー同様、ruby コマンドの引数に videodata っていうファイル名を喰わして

> ruby -F'\t' -ane “system('wget', '-O' + \$F[1].chomp() +'.divx', 'http://video.stage6.com/' + \$F[0] + '/.divx') unless File.exist?(\$F[1].chomp() +'.divx')“ videodata


こうすればそれだけで実行出来るのだけど、わざわざ cat で吐いているのは、実際には videodata を更に分割して screen 使って並列実行したり、更にそれだけじゃ足りなくなって、上の cat の部分を tac に変えて逆順でさらに並列実行数を増やしたり、という事を行ったから。


それでも 2500 個くらいあったファイルの内の 700 個強、80GB くらいを DL したところで Stage6 が止まってしまった。残念。
とは言え、冒頭でも書いた通り、目的は既にワンライナーで遊ぶ事になっていたのでこれで充分楽しかった。集めた動画も見るのかどうか・・・。


おまけとして、応用編。シェルを叩くのは頭の体操みたいでホントおもろい。ルールを毎回忘れてるのが困るけど。


一つ目は、初期にスクリプトのミスで出来てしまった0バイトのファイルだけを消す方法

> for f in *; do if [ -f “$f“ -a ! -s “$f“ ]; then rm -- “$f“; fi; done


これだけなら、並べ変えてドラッグで選択→右クリックで「削除」の GUI のが楽かも。もしリモート操作の時などに必要が生じたら。


同様にミスで出来た、ファイル名の先頭に半角スペースが入ってしまったファイルをリネームして半角スペースを消す方法も。if 文は要らんかも。expr で substr とか length とか文字列演算が出来るなんて初めて知ったよorz

> for f in \ *; do if [ -f “$f“ ]; then mv “$f“ “`expr substr “$f“ 2 length “$f“`“ ; fi; done