動画データを取得する その6
Javaでニコニコ動画をゴニョゴニョする作戦 第1.9弾。
夏バテやら夏休みやらモチベーションがさがったりで中々進まなかったわけで。
今日は時間が出来たのでゆっくりソースかいてみた。
- 今までやってきたこと
というわけでさっそくソースを晒していこう
package analyzer; 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 bean.TagBean; import bean.ThumbInfoBean; import com.sun.org.apache.xerces.internal.parsers.DOMParser; import exception.NiconicoException; public class XmlPather { public ThumbInfoBean analyzer(InputStream is) throws NiconicoException, SAXException, IOException { try { DOMParser parser = new DOMParser(); parser.parse(new InputSource(is)); Document document = parser.getDocument(); if (document.hasChildNodes()) { ThumbInfoBean thumbInfo = new ThumbInfoBean(); thumbInfo.setResponseStatus(getStatus(document)); if(getStatus(document).equals("ok")){ thumbInfo.setVideoId(getNodeValue(document,"video_id")); thumbInfo.setTitle(getNodeValue(document,"title")); thumbInfo.setDescription(getNodeValue(document,"description")); thumbInfo.setThumbnailUrl(getNodeValue(document,"thumbnail_url")); thumbInfo.setFirstRetrive(getNodeValue(document,"first_retrieve")); thumbInfo.setLength(getNodeValue(document,"length")); thumbInfo.setViewCounter(getNodeValue(document,"view_counter")); thumbInfo.setCommentNum(getNodeValue(document,"comment_num")); thumbInfo.setMylistCounter(getNodeValue(document,"mylist_counter")); thumbInfo.setLastResBody(getNodeValue(document,"last_res_body")); thumbInfo.setWatchUrl(getNodeValue(document,"watch_url")); thumbInfo.setThumbType(getNodeValue(document,"thumb_type")); thumbInfo.setTagArray(getTagArray(document)); }else{ thumbInfo.setCode(getNodeValue(document,"code")); thumbInfo.setDescription(getNodeValue(document,"description")); } return thumbInfo; } else { throw new NiconicoException("childNode not found"); } } catch (SAXException e) { throw e; } catch (IOException e) { throw e; } } /** * レスポンスステータスを取得 * @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<TagBean> getTagArray(Document document){ ArrayList<TagBean> resultList = new ArrayList<TagBean>(); NodeList tagsList = document.getElementsByTagName("tags"); for(int i=0;i<tagsList.getLength();i++){ Node tags = tagsList.item(i); //domain取得 String domain = tags.getAttributes().getNamedItem("domain").getNodeValue(); //子ノードを取得 NodeList childList = tags.getChildNodes(); for (int j=0;j<childList.getLength();j++){ TagBean tagBean = new TagBean(); if(childList.item(j).getNodeType() == Node.ELEMENT_NODE){ tagBean.setDomain(domain); tagBean.setTag(childList.item(j).getTextContent()); if(childList.item(j).getAttributes().getNamedItem("lock") != null){ tagBean.setLockStatus(childList.item(j).getAttributes().getNamedItem("lock").getNodeValue()); } resultList.add(tagBean); } } } return resultList; } }
XML新仕様に関しては前回のエントリ(こちら)を参照してね
変更されたのは主にtag情報についての部分。ロック状態、海外タグについての対応が入った。
成功時は以下のように返却されています
1ksp:6のときの動画のデータ(id:nishiohirokazuの発表 動画)を引っ張ってます。
<?xml version="1.0" encoding="UTF-8"?> <nicovideo_thumb_response status="ok"> <thumb> <video_id>sm4231432</video_id> <title>Pythonで作ったひどいものまとめ - nishio</title> <description>1000speakers:6</description> <thumbnail_url>http://tn-skr1.smilevideo.jp/smile?i=4231432</thumbnail_url> <first_retrieve>2008-08-09T14:05:43+09:00</first_retrieve> <length>9:09</length> <view_counter>262</view_counter> <comment_num>32</comment_num> <mylist_counter>5</mylist_counter> <last_res_body>おもしりかった w debugしたくない おもしろかったです! しかも正方形wwwwww wwwwww 1000回 えぇ... </last_res_body> <watch_url>http://www.nicovideo.jp/watch/sm4231432</watch_url> <thumb_type>video</thumb_type> <tags domain="jp"> <tag>ニコニコ動画講座</tag> <tag>1000speakers:6</tag> <tag>1000speakers</tag> <tag>TechTalk</tag> <tag>Python</tag> <tag>サイトウサン</tag> </tags> </thumb> </nicovideo_thumb_response>
つづいてエラー時
<?xml version="1.0" encoding="UTF-8"?> <nicovideo_thumb_response status="fail"> <error> <code>NOT_FOUND</code> <description>not found or invalid</description> </error> </nicovideo_thumb_response>
ステータスとしてfailが帰ってきてcodeにエラーコードが入ってる。
このcodeはエラーのときのみ出現する。descriptionにはエラー内容が入ってる。
ソースの中ではそれにより場合分けしてる。
全体的なエラーハンドリングとしては、
を実装。(上位にスローするだけだがw)
タグの内容についてはTagBeanに、動画データはThumbInfoBeanに格納している
TagBean.java
package bean; import java.io.Serializable; public class TagBean implements Serializable{ private static final long serialVersionUID = -3223265583035963758L; private String lockStatus = ""; private String domain = ""; //以下略 アクセサがあるだけ
ThumbInfoBean.java
package bean; import java.io.Serializable; import java.util.ArrayList; public class ThumbInfoBean implements Serializable { private static final long serialVersionUID = -1404974738386093736L; private String responseStatus = ""; private String videoId = ""; private String title = ""; private String description = ""; private String thumbnailUrl = ""; private String firstRetrive = ""; private String length = ""; private long viewCounter = 0; private long commentNum = 0; private long mylistCounter = 0; private String lastResBody = ""; private String watchUrl = ""; private String thumbType = ""; private ArrayList<TagBean> tagArray = new ArrayList<TagBean>(); //以下略 アクセサがあるだけ
こんなかんじでデータをそれぞれのBeanに格納してます。
サンプルとしてこんな感じでやると画面に表示できる。
package test; import java.io.InputStream; import java.util.ArrayList; import bean.TagBean; import bean.ThumbInfoBean; import analyzer.XmlPather; import connect.HttpConnector; public class Test { public static void main(String[] args) { try{ HttpConnector connector = new HttpConnector(); InputStream is = connector.getVideoInfo(args[0]); XmlPather parther = new XmlPather(); ThumbInfoBean thumbInfo = parther.analyzer(is); //レスポンスステータス System.out.println("resuponse Status:"+thumbInfo.getResponseStatus()); //動画ID System.out.println("video_id:"+thumbInfo.getVideoId()); //動画タイトル System.out.println("title:"+thumbInfo.getVideoId()); //動画説明文 System.out.println("description:"+thumbInfo.getDescription()); //サムネイルURL System.out.println("thumbnail_url:"+thumbInfo.getThumbnailUrl()); //投稿時間 System.out.println("first_retrieve:"+thumbInfo.getFirstRetrive()); //動画時間 System.out.println("length:"+thumbInfo.getLength()); //再生数 System.out.println("view_counter:"+thumbInfo.getViewCounter()); //コメント数 System.out.println("comment_num:"+thumbInfo.getCommentNum()); //マイリスト登録数 System.out.println("mylist_counter:"+thumbInfo.getMylistCounter()); //最新コメント System.out.println("last_res_body:"+thumbInfo.getLastResBody()); //動画URL System.out.println("watch_url:"+thumbInfo.getWatchUrl()); //動画種類 System.out.println("thumb_type:"+thumbInfo.getThumbType()); ArrayList<TagBean> tagArray = thumbInfo.getTagArray(); for(TagBean tag:tagArray){ //タグ System.out.println("domain:"+tag.getDomain()); System.out.println("lock:"+tag.getLockStatus()); System.out.println("tag:"+tag.getTag()); System.out.println(""); } }catch(Exception e){ e.toString(); } } }
今回で大体の目標とした動画データの取得とかのお話はほぼ完成。
まとめて一回どこかで晒そうかと思います。CodeReposとかにAKYS*2するとか。
ググってみたけどJavaのニコ動APIラッパーってないみたい。(rubyはある)
そんな感じでーす