動画データを取得する その4

Javaニコニコ動画Javaでゴニョゴニョする作戦 第1.81弾。
ソースが書きあがった瞬間に地震がきてびっくりした。
ちょっとドキドキして寝れないので今のうちソースなどをうpする。

今回は動画データXMLをパースしたりするところまで実装した。

前回は一つだけの要素をとってきて表示としていた部分から、全タグを取得
して表示するという形に変えた。

というわけで早速ソース晒し。

XmlPather.java

package xmlParther;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;


import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.sun.org.apache.xerces.internal.parsers.DOMParser;

public class XmlPather {

  public void analyzer(InputStream is){
    try {

      DOMParser parser = new DOMParser();
      parser.parse(new InputSource(is)); 

      Document document = parser.getDocument();

      if (document.hasChildNodes()) {
        //レスポンスステータス
        System.out.println("resuponse Status:"+getStatus(document));
        //動画ID
        System.out.println("video_id:"+getNodeValue(document,"video_id"));
        //動画タイトル
        System.out.println("title:"+getNodeValue(document,"title"));
        //動画説明文
        System.out.println("description:"+getNodeValue(document,"description"));
        //サムネイルURL
        System.out.println("thumbnail_url:"+getNodeValue(document,"thumbnail_url"));
        //投稿時間
        System.out.println("first_retrieve:"+getNodeValue(document,"first_retrieve"));
        //動画時間
        System.out.println("length:"+getNodeValue(document,"length"));
        //再生数
        System.out.println("view_counter:"+getNodeValue(document,"view_counter"));
        //コメント数
        System.out.println("comment_num:"+getNodeValue(document,"comment_num"));
        //マイリスト登録数
        System.out.println("mylist_counter:"+getNodeValue(document,"mylist_counter"));
        //最新コメント
        System.out.println("last_res_body:"+getNodeValue(document,"last_res_body"));
        //動画URL
        System.out.println("watch_url:"+getNodeValue(document,"watch_url"));
        //動画種類
        System.out.println("thumb_type:"+getNodeValue(document,"thumb_type"));
        
        ArrayList<String> tagArray = getTagArray(document);
        for(String tag:tagArray){
          //タグ
          System.out.println("tag:"+tag);
        }
        
        
      } else {
        System.out.println("DOCUMENTノードに子ノードがありません。");
      } 
    } catch (SAXException e) { 
      System.out.println("XMLデータが不正です。");
      e.printStackTrace();
    } catch (IOException e) { 
      e.printStackTrace();
    }

  }
  
  /**
   * レスポンスステータスを取得
   * @param document
   * @return
   */
  private String getStatus(Document document){
    String status = "";
    NodeList nodeList = document.getElementsByTagName("nicovideo_thumb_response");
    Node node = nodeList.item(0);
    NamedNodeMap hoge = node.getAttributes();
    status = hoge.getNamedItem("status").getNodeValue();
    return status;
  }
  
  /**
   * 各Nodeの内容を取得(ノードが一意のもの tag以外)
   * @param document
   * @param tagName
   * @return
   */
  private String getNodeValue(Document document,String tagName){
    String value = "";
    NodeList nodeList = document.getElementsByTagName(tagName);
    Node node = nodeList.item(0);
    value = node.getTextContent();
    return value;
  }
  
  /**
   * 各Nodeの内容を取得(同一名のノードが複数あるもの tag)
   * @param document
   * @return
   */
  private ArrayList<String> getTagArray(Document document){
    ArrayList<String> tagArray = new ArrayList<String>();
    NodeList nodeList = document.getElementsByTagName("tag");
    for(int i=0;i<nodeList.getLength();i++){
      Node node = nodeList.item(i);
      tagArray.add(node.getTextContent());
    }
    return tagArray;
    
  }
}

ニコニコ動画データXML

  • attributeからとるレスポンスのステータス
  • タグ名とタグが1:1になる要素(同一のタグエレメントが複数存在しない tag以外)
  • タグ名とタグが1:nになる要素(同一のタグエレメントが複数存在する tag)

の3パターン。
なのでそれに合わせてgetStatus,getNodeValue,getTagArrayの3つのprivate method
を実装した。

簡単に解説

Document document = parser.getDocument();

XMLをパース。XMLがおかしいとSAXExceptionが発生。

NodeList nodeList = document.getElementsByTagName(tagName);

でタグ名を指定して該当するタグの部分(Node)を取得。
同じ名前のタグエレメントが複数あればNodeListに複数の要素が入って返却される。
各ノードの取得は1つしかないとこは0キメ打って取得。複数あるとこはループ回して取得。

Attributeをとりたいときは

NamedNodeMap hoge = node.getAttributes();

でNamedNodeMapを生成。

hoge.getNamedItem(アトリビュート名).getNodeValue();

で値を取得。

でもって出力結果。

URL: http://www.nicovideo.jp/api/getthumbinfo/sm4005866
resuponse Status:ok
video_id:sm4005866
title:【MAD】時をかける少女 ガーネット【H.264】
description:以前UPしていたMADをH.264でエンコードし、MAD自体も微調整をして再UPしてみました! H.264エンコは初めてなので、試行錯誤の結果、できるかぎり高画質にUPしたつもりです(^^;
thumbnail_url:http://tn-skr1.smilevideo.jp/smile?i=4005866
first_retrieve:2008-07-19T09:54:07+09:00
length:5:22
view_counter:96309
comment_num:9148
mylist_counter:4779
last_res_body:こんなにいいと思った きたあああ ii 空気よめ ここは・・・・・・・ ここよす... 
watch_url:http://www.nicovideo.jp/watch/sm4005866
thumb_type:video
tag:アニメ
tag:時をかける少女
tag:ガーネット
tag:跨越時空的中年
tag:AMV
tag:The_Girl_Who_Leapt_Through_Time
tag:Time_waits_for_no_one
tag:sm3723821
tag:←(゚Д゚)ハァ?
tag:奥華子
tag:細田守
tag:ガーネット←真琴目線
tag:至高の名曲リンク
tag:NGユーザー大量発生

こんなかんじ。
エラーパターンのXMLのパースが出来てないから、そちらにも対応する予定。

こんな感じでーす。