phpNico改悪してPHPでニコニコ動画をさらにごにょごにょさせてみる。


ゆーすけべー日記dankogaiが添削して話題ですが,あんまり評価されてないニコニコ用PHPライブラリを発見。


http://svn.riaf.org/phpnico/phpNico/trunk/
PHPでニコニコ動画をごにょごにょする - WebProgを極めて居酒屋を開発する


動画のIDからコメントの取得ができるっぽい。動画の取得は未対応。コメント書き込みやコメントファイルを読み込んでvpos等で並べる機能とかもあるみたいだけど,自分はチェックしてないので動くのかは不明。*1


面白そうなのでいじってみて,仕様変更への未対応といくつか不満なとこがあったので改悪してみた。だいたい以下のあたりを改悪。


まずphpNico.phpの61行目あたり。

    function getVideo($video_id, $object=false){
        $thread_id = $this->_parseId($video_id);// いらないかもしれない。
        if($thread_id == false){
            return null;
        }
        $this->client->get($this->nicourl . 'getflv?v=' . $thread_id);

    function getVideo($video_id, $object=false){
        if($video_id == false){
            return null;
        }
        $this->client->get($this->nicourl . 'api/getflv?v=' . $video_id);


$this->_parseId($video_id) は元ソースでも書いてあるけど不要。つーか残しておくと毎回動画ページを読みにいって余計なリクエストを増やすのでコメントアウト。あとgetflvのURLが変更されてるので反映。
phpNico.phpはこれだけ。


もう一個のphpNico_VideoObject.phpは,まずなんか不具合の出てるfunction getVideoInfo()(130行目あたり)をコメントアウト
次にまだ出来てないsaveVideo(flvをダウンロードして保存)を以下のように上書き。

    function saveVideo($filename){
        $this->client->get($this->nicourl . 'watch/' . $this->getThreadId());
        $this->client->get($this->getFlvUrl());
        $response = $this->client->currentResponse();
        $fp = fopen($filename,"w");
        fwrite($fp,$response['body']);
        fclose($fp);
    }


動画の取得はこれを参考にした。
[php] PHPでニコニコ動画をダウンロードする方法 その1 - goinger的日記
もっともHTTP_CLIENTを使えば普通にセッション管理できるので非常にラクに書ける。


あとwaybackkeyの取得と,コメント取得機能を改変して過去ログ取得機能を書く。*2

    function _getWaybackkey(){
        if($this->is_premium == 1){
            $this->client->get($this->nicourl . 'api/getwaybackkey?thread=' . $this->getThreadId());
            $response = $this->client->currentResponse();
            parse_str($response['body'], $data);
            $this->waybackkey = $data['waybackkey'];
            return $this->waybackkey;
        }else{
            return false;
        }
    }
    function _getArchiveMessageXML($when,$offset='-1000'){
    	if(!isset($this->waybackkey)){
    	    if($this->is_premium == 1){
    	        $this->_getWaybackkey();
    	    }else{
	        return false;
	    }
    	}
        $xml  = sprintf(
            '<thread user_id="%s" when="%s" waybackkey="%s" res_from="%s" version="20061206" thread="%s" />',
            $this->getUserId(),
            $when,
            $this->waybackkey,
            $offset,
            $this->getThreadId()
        );
        $req = new HTTP_Request($this->getMessageServer());
        $req->setMethod(HTTP_REQUEST_METHOD_POST);
        $req->addRawPostData($xml);
        $r = $req->sendRequest();
        if(PEAR::isError($r)){
            return null;
        }
        return $req->getResponseBody();
    }


以上。ちなみにソースは雑です。あとオブジェクト指向とかもよくわからんのでPEARで拾ったあとに直接ソースいじってます。所詮おいらは図書館の司書さんです。上記の改変ソースは勝手に使っていいのでそのへんはなんかうまいふうにしちゃって下さい。


使い方はオリジナルと同様に

<?php
require 'phpNico.php';
$video_id = 'sm*****とか。';// 自分はCLIでいじるので $video_id = $argv[1]; とか書く。
$option = array('mail' => 'your mail address', 'password' => 'your password');
$nico = new phpNico($option);
$nico->connect();
$video = $nico->getVideo($video_id, true);
...

した後に,

$video->saveVideo($video_id.".flv");


でsm*****.flvに動画を保存。

$time = "***********";//UNIXのタイムスタンプで取得したい日時を指定。
$filename = $video_id."_archive.xml";
$f = fopen($filename,"w");
fwrite($f, $video->_getArchiveMessageXML($time));
fclose($f);


で過去ログのXMLを取得してファイルに保存という感じ。もちろんプレミアム会員のID使わないとできませんが。
これを使ってたとえばこんなふうにすれば過去ログを根こそぎ落とせるはず。

<?php
require 'phpNico.php';
$video_id = "sm******";
$lim = 100000;//取得したいコメント数の目安を指定。
$option = array('mail' => 'your mail address', 'password' => 'your password');
$nico = new phpNico($option);
$nico->connect();
$video = $nico->getVideo($video_id, true);
$time = time();
for($j=0;$j < $lim/1000;$j++){
   $res = $video->_getArchiveMessageXML($time);
   $xml = simplexml_load_string($res);
   if(!$xml->chat){exit;}
   $time = $xml->chat["date"];//一番古い米の時間を取得。
   $f = fopen($video_id."-".$j.".xml","w");
   fwrite($f, $res);
   fclose($f);
   sleep(1);//サーバ負荷を考えて1秒待つ。いらんかもっと短くていいかも。
}


ちなみに組曲のコメント解析は,こういう感じの*3にさらにXMLをタブ区切りテキストに変換するのをかませて,それをMS ACCESSにつっこんでやってます。もっと上手い方法はいくらでもあるだろうけどやりやすかったので。
まあソースの公開の仕方とかよくわからん人なので,過去ログとかはだいたいこんな感じで拾えるよという一例。
さ,組曲解析の続きやろう。

*1:つうかaddCommentはさすがに不味いような……黄色みたいなのとか呼びそう。

*2:通常のコメント取得と過去ログ取得をまとめちゃってもいいのかもしれない。

*3:当時は一部手作業,一部さらに雑なスクリプトで拾ってましたが