日記

ニコニコ動画のコメントをJavaで取得 [プログラム関係]

学校の課題で何かプログラム作ることになって、
僕はニコニコ動画のコメントを取得するして
2chブラウザ的に閲覧できるプログラムを作ろうと思ったので
今日はコメント取得についていろいろ調べてました。
JavaでCookieとかも扱ったことなかったので少々つらかったです。

んでまとめると、
・ニコニコにログイン
・ログインした時もらうCookieでhttp://www.nicovideo.jp/api/getflv/(動画ID)へアクセス。
・するとなんかクエリが帰ってくる。
・そのクエリのsm=のとこがその動画のメッセージサーバーのURL。
・その動画のthread_idがその動画のスレッドID。
・メッセージサーバーにXML(後述のソースで割合)を投げる。
・コメントXMLが帰ってくる。
こんな流れみたいです。

ちなみにコメントじゃなくて動画名・コメント数・新着コメント程度なら
http://www.nicovideo.jp/api/getthumbinfo/(動画ID)
を叩くだけでそれらの情報の入ったXMLがもらえるので
新着コメント数を知りたいだけとかならこちらを使うほうが
速いし向こうの鯖にも迷惑をかけない模様です。


URL url;
HttpURLConnection conn;
BufferedWriter writer;
BufferedReader reader;
String cookie;
String[] response, strs;
HashMap<String, String> data;

url = new URL("https://secure.nicovideo.jp/secure/login?site=niconico");
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.connect();
writer = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
writer.write("mail=" + URLEncoder.encode(MAIL, "UTF-8"));
writer.write("&password=" + URLEncoder.encode(PASSWORD, "UTF-8"));
writer.flush();
writer.close();
cookie = conn.getHeaderField("Set-Cookie");
conn.disconnect();

url = new URL(http://www.nicovideo.jp/api/getflv/+id);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Cookie", cookie);
conn.connect();
reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
response = reader.readLine().split("&");
conn.disconnect();

data = new HashMap<String, String>();
for (String s : response)
{
	strs = URLDecoder.decode(s, "UTF-8").split("=");
	data.put(strs[0], strs[1]);
}

url = new URL(data.get("ms"));
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.connect();
writer = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
writer.write("<thread res_from=\"-500\" version=\"20061206\" thread=\"");
writer.write(data.get("thread_id") + "\" />");
writer.flush();
writer.close();

DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dbfactory.newDocumentBuilder();
Document doc = builder.parse(conn.getInputStream());
...
conn.disconnect();

try文とかは割合。
あとコードが汚い。


at 2009-6-8 0:16 | Comment(4)
Comment by redhat98 ◆Oamxnad08k at 2009-7-13 23:07 削除
私は専門学生で人の事をあーだこーだ言えませんが、
IOUtils.closeQuietly(wrter);と書くと例外の処理が楽になりますよ。
あと、IOUtils.readLinesとかも便利かもしれません。
apache commons ioでgoogleとかで検索すると、このクラスはもう少し簡単に書ける気がします
私もApacheにこんな便利なものがあるとは最近まで知りませんでした。親切な人が教えてくれるまでは....
Comment by mana. ★ at 2009-7-14 18:21
コメントありがとうございます。

Javaの通信関係はほとんどいじったことないのでよくわかってないのですが、
なるほど便利なライブラリがあるわけですね。
Comment by mana. ★ at 2009-7-14 18:21
ソースを見たらcloseQuietlyはただIOExceptionをキャッチして
無視するだけのメソッドでしたので他のExceptionも考慮して
全体をtry-catchで囲むことを考えると今回はあまり必要でない気がします。
ただし例外がcloseから発生していないことを確実にするので
エラーチェックは多少楽になると思います。
おそらくcloseが致命的なエラーを吐かないという仮定のもと、このようなメソッドがあるのでしょう。
Comment by mana. ★ at 2009-7-14 18:22
readLinesはReaderの中身を読み切ってArrayListで返すメソッドみたいですね。
今回のように読み込みストリームの全体が必要ない場合は
むしろ逆効果になるので(パフォーマンス面で)注意したほうがよさそうです。

有益な情報ありがとうございました。
名前: 削除パス: 非公開
URL:
添付:(jpg,gif,png,200KBまで)

 
required 0.0310 sec