スライドもなんとか上がったので、リハビリもかねて久々の添削。

camel Perlでニコニコ動画のflvとコメントxmlをダウンロードする (Yusukebe::Tech)
さんざん既出かもしれないけどPerlでニコニコ動画のflvファイルとコメントのxmlファイルをダウンロードするスクリプト。

まずは結果から。

#!/usr/bin/env perl
#
# $Id: nicoget.pl,v 0.1 2007/08/03 19:26:19 dankogai Exp dankogai $
# original: http://yusukebe.com/tech/archives/20070803/124356.html
#

use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Cookies;
use HTTP::Request;
use HTTP::Headers;
use CGI;
use YAML::Syck;

my $yaml = "$ENV{HOME}/.nicovideo.yml";
my $conf = YAML::Syck::LoadFile($yaml) or die "$yaml:$!";
$ARGV[0] =~ /(sm\d+)$/ or die "$0 [video_id|uri]";
my $video_id = $1;

my $ua = LWP::UserAgent->new( keep_alive => 4 );
$ua->cookie_jar( {} );

warn "login as $conf->{mail}\n";
$ua->post( "http://www.nicovideo.jp/login" => $conf );
$ua->get("http://www.nicovideo.jp/watch/$video_id");
my $res = $ua->get("http://www.nicovideo.jp/api/getflv?v=$video_id");
my $q   = CGI->new( $res->content );
my $url = $q->param('url') or die "Failed: " . $res->content;
warn "$url => $video_id.flv\n";
$res = $ua->request( HTTP::Request->new( GET => $url ), "$video_id.flv" );

以上でvideoのみget。以下を足すことでコメントもget。

warn "saving comments as $video_id.xml\n";
my $header = HTTP::Headers->new;
$header->header( Content_Type => 'text/xml' );
my $thread_id = $q->param('thread_id');
my $req       = HTTP::Request->new(
    POST => $q->param('ms'),
    $header,
    qq{<thread res_from="-500" version="20061206" thread="$thread_id" />}
);
$res = $ua->request( $req, "$video_id.xml" );

変更点は、以下のとおり。

  • ユーザー名(mail)とパスワード(password)は、~/.nicovideo.ymlに移動。フォーマットは
    mail:     your@host.name
    password: yourpassword
    
  • UAでKeep Aliveを有効に。少しでも鯖をニコニコさせたいので。
  • cookieは、必ずloginするので非保存に。
  • queryの処理はCGIモジュールにおまかせ
  • 一瞬で終わるスクリプトではないので、進捗表示とエラー処理追加
  • ビデオIDだけではなく、フルURIを引数に指定可能に。この方が何かと楽。
  • ファイルへの保存をLWPに直接おまかせ。この方が$res->contentを使うよりメモリー節約になる。
  • コードの大幅な簡素化

Enjoy!

Dan the Nicophile Perl Monger