Fork me on GitHub

2008/10/27

Recent entries from same category

  1. 携帯電話からIRCが出来る!Freenode専用モバイルゲートウェイ書いた Hatena
  2. WindowsのPerl(mingw32)でもCoroを動かすパッチ。 Hatena
  3. DBD::SQLiteで正規表現SQLを使う Hatena
  4. githubでどのプロジェクトのコラボレータになったのか思い出せるPerlスクリプト Hatena
  5. PerlからGNTP(Growl Notification Transport Protocol)で送信出来るモジュール書いた。 Hatena

はてな
miyagawaさんがPlaggerのFetchNicoVideoからダウンローダとして抜き出してくれました。
Tatsuhiko Miyagawa / WWW-NicoVideo-Download-0.01 - search.cpan.org
http://search.cpan.org/~miyagawa/WWW-NicoVideo-Download-0.01/
中身はMooseを使ったモダンなコード。eg/fetch-video.plにそのまま使えそうなサンプルまで入っています。
サンプルではTerm::ProgressBarで進捗表示までされて至れり尽くせり。今日はちょっとだけ修正してファイル名をタイトルから名付ける様にしてみました。
といってもWWW::NicoVideo::Downloadではloginが単体で呼び出せられる様になっていますし、user_agentが得られるようになっているのでそれを同じくmiyagawaさん作のWeb::Scraperに渡しただけです。
#!/usr/bin/perl
use strict;
use warnings;
use Encode qw(encode decode_utf8);
use URI;
use Web::Scraper;
use WWW::NicoVideo::Download;
use Term::ProgressBar;

my($email, $password, $video_id) = @ARGV;

my($term, $fh);

my $client = WWW::NicoVideo::Download->new( email => $email, password => $password );
$client->login( $video_id );

my $helper = scraper { process '#subinfo img', title => '@alt' };
$helper->user_agent( $client->user_agent );

my $title = $helper->scrape(
    URI->new("http://www.nicovideo.jp/watch/$video_id")
)->{title} || $video_id;
$title = encode("cp932", decode_utf8($title)) if $^O eq 'MSWin32';

$client->download($video_id, \&cb);

sub cb {
    my($data, $res, $proto) = @_;

    unless ($term && $fh) {
        my $ext = (split '/', $res->header('Content-Type'))[-1] || "flv";
        my $filename = "$title.$ext";
        $filename =~ s![\\/|:<>"?*]!_!g;
        open $fh, ">", $filename or die $!;
        $term = Term::ProgressBar->new( $res->header('Content-Length') );
    }

    $term->update( $term->last_update + length $data );
    print $fh $data;
}
うむ。便利便利。

そういえばWEB+DB PRESS vol47買った。codereposの記事も面白かった。

WEB+DB PRESS Vol.47 WEB+DB PRESS Vol.47
WEB+DB PRESS編集部
技術評論社 / ¥ 1,554 (2008-10-24)
 
発送可能時間:在庫あり。


追記
otsuneさんから、API叩いた方が仕様変更に強いとコメント頂きました。XML::Simple使ってタイトル取る様に修正しました。
#!/usr/bin/perl
use strict;
use warnings;
use Encode qw(encode decode_utf8);
use XML::Simple;
use WWW::NicoVideo::Download;
use Term::ProgressBar;

my($email, $password, $video_id) = @ARGV;

my($term, $fh);

my $client = WWW::NicoVideo::Download->new( email => $email, password => $password );
$client->login( $video_id );

my $res = $client->user_agent->get("http://www.nicovideo.jp/api/getthumbinfo?v=$video_id");
my $title = $video_id;
if ($res->is_success) {
  my $xs = XML::Simple->new;
  my $ref = $xs->XMLin($res->decoded_content);
  $title = $ref->{thumb}->{title} || $video_id;
  $title = encode("cp932", decode_utf8($title)) if $^O eq 'MSWin32';
}

$client->download($video_id, \&cb);

sub cb {
    my($data, $res, $proto) = @_;

    unless ($term && $fh) {
        my $ext = (split '/', $res->header('Content-Type'))[-1] || "flv";
        my $filename = "$title.$ext";
        $filename =~ s![\\/|:<>"?*]!_!g;
        open $fh, ">", $filename or die $!;
        $term = Term::ProgressBar->new( $res->header('Content-Length') );
    }

    $term->update( $term->last_update + length $data );
    print $fh $data;
}

blog comments powered by Disqus blog comments powered by Disqus
WriteBacks

タイトルなど各種情報だけとるんなら

www.nicovideo.jp/api/getthumbinfo/$video_id を使ったほうが軽いし変化にもつよくね?

Posted by otsune at 2008/10/28 (Tue) 15:19:06

Re: タイトルなど各種情報だけとるんなら

ありがとうございます。修正してみました。

Posted by mattn at 2008/10/28 (Tue) 18:40:43

TrackBack ping me at
Post a comment

writeback message: Ready to post a comment.