【ニコニコ動画】コメント取得

ログインしたセッション、コメントサーバURL、ユーザID、スレッドIDを利用し、
コメントを取得します。

  • HTTP通信開始

    // HTTP通信を開始する。
    URL url = new URL(commentServer);
    HttpURLConnection http = (HttpURLConnection)url.openConnection();
    
  • リクエストヘッダ部設定

    // リクエストヘッダ部を設定する。
    http.setRequestMethod("POST");
    http.setDoOutput(true);
    // XML形式を指定する。
    http.setRequestProperty("Content-Type", "text/xml");
    // セッションと動画用クッキーを設定する。
    http.setRequestProperty("Cookie", "user_session=" + userSession);
    
  • リクエストボディ部設定

    // リクエストボディ部を設定する。
    PrintStream ps = new PrintStream(http.getOutputStream());
    StringBuilder xml = new StringBuilder();
    xml.append("<thread ");
    // スレッドIDを設定する。
    xml.append("thread=\"" + threadId + "\" ");
    // 固定値を設定する。
    xml.append("version=\"20061206\" ");
    // 取得コメント数を設定する。一般会員の場合、最大で1000件となる。
    xml.append("res_form=\"-100\" ");
    // ユーザIDを設定する。
    xml.append("user_id=\"" + userId + "\" ");
    xml.append("/>");
    ps.print(xml.toString());
    ps.close();
    
  • レスポンスボディ部取得

    // レスポンスボディ部を取得する。
    String comment = null;
    BufferedReader br = new BufferedReader(new InputStreamReader(http.getInputStream()));
    while((comment = br.readLine()) != null) {
        // XML形式のため、整形する必要がある。
        System.out.println(comment);
    }
    br.close();
    
  • レスポンスヘッダ部の取得は不要です。

【ニコニコ動画】動画取得

ログインしたセッション、動画サーバURL、動画拡張子、動画用クッキーを利用し、
動画を取得します。
一般会員、プレミアム会員によって動画サイズが異なる事象あり。
プレミアム会員の方が解像度が高そうです。

  • HTTP通信開始

    // HTTP通信を開始する。
    URL url = new URL(movieServer);
    HttpURLConnection http = (HttpURLConnection)url.openConnection();
    
  • リクエストヘッダ部設定

    // リクエストヘッダ部を設定する。
    http.setRequestMethod("GET");
    // セッションと動画用クッキーを設定する。
    http.setRequestProperty("Cookie", "user_session=" + userSession + "; nicohistory=" + nicoHistory);
    
  • GET通信のため、リクエストボディ部の設定は不要です。

  • レスポンスボディ部取得

    // レスポンスボディ部を取得する。
    InputStream in= http.getInputStream();
    File file = new File("D:/", "sm12345678" + movieExtension);
    Files.copy(in, file.toPath());
    in.close();
    
  • レスポンスヘッダ部の取得は不要です。

【ニコニコ動画】動画用クッキー取得

ログインしたセッションを維持して、
「http://www.nicovideo.jp/watch/sm12345678」にGET通信し、
動画用のクッキーを取得します。

  • HTTP通信開始

    // HTTP通信を開始する。
    URL url = new URL("http://www.nicovideo.jp/watch/sm12345678");
    HttpURLConnection http = (HttpURLConnection)url.openConnection();
    
  • リクエストヘッダ部設定

    // リクエストヘッダ部を設定する。
    http.setRequestMethod("GET");
    // セッションを設定する。
    http.setRequestProperty("Cookie", "user_session=" + userSession);
    
  • GET通信のため、リクエストボディ部の設定は不要です。

  • レスポンスヘッダ部取得

    // レスポンスヘッダ部を取得する。
    String nicoHistory = null;
    Map<String, List<String>> responseHeaders = http.getHeaderFields();
    Iterator<String> responseIt = responseHeaders.keySet().iterator();
    while (responseIt.hasNext()) {
        String responseKey = responseIt.next();
        List<String> responseList = responseHeaders.get(responseKey);
        for(String reponseValue: responseList) {
            System.out.println(responseKey + ":" + reponseValue);
            if ("Set-Cookie".equals(responseKey)) {
                String[] cookieAry = reponseValue.split(";");
                for (String cookie: cookieAry) {
                    String[] nicoHistoryAry = cookie.split("=");
                    if ("nicohistory".equals(nicoHistoryAry[0])) {
                        nicoHistory = nicoHistoryAry[1];
                    }
                }
            }
        }
    }
    
  • レスポンスボディ部の取得は不要です。

【ニコニコ動画】動画情報取得

ログインしたセッションを維持して、
「http://flapi.nicovideo.jp/api/getflv/sm12345678」にGET通信し、
以下の動画情報を取得します。

  • 動画サーバURL
    APIのレスポンスボディ部のうち、
    「url=http%3A%2F%2Fsmile-pow64.nicovideo.jp%2Fsmile%3Fm%3D11111111.11111」を取得します。
    URLデコードしておく必要があります。
    「http://smile-pow64.nicovideo.jp/smile?m=11111111.11111」となります。
  • 動画拡張子
    動画サーバURLのパラメータから判断します。
    パラメータが「m」の場合、動画拡張子が「.mp4」、
    パラメータが「s」の場合、動画拡張子が「.swf」、
    パラメータが上記以外の場合、動画拡張子が「.flv」になります。
  • コメントサーバURL
    APIのレスポンスボディ部のうち、
    「ms=http%3A%2F%2Fnmsg.nicovideo.jp%2Fapi%2F」を取得します。
    URLデコードしておく必要があります。
  • ユーザID
    APIのレスポンスボディ部のうち、
    「user_id=11111」を取得します。
  • スレッドID
    APIのレスポンスボディ部のうち、
    「thread_id=1111111111」を取得します。
  • HTTP通信開始

    // HTTP通信を開始する。
    URL url = new URL("http://flapi.nicovideo.jp/api/getflv/sm12345678");
    HttpURLConnection http = (HttpURLConnection)url.openConnection();
    
  • リクエストヘッダ部設定

    // リクエストヘッダ部を設定する。
    http.setRequestMethod("GET");
    // セッションを設定する。
    http.setRequestProperty("Cookie", "user_session=" + userSession);
    
  • GET通信のため、リクエストボディ部の設定は不要です。

  • レスポンスボディ部取得

    // レスポンスボディ部を取得する。
    String str = null;
    String movieServer = null;
    String movieExtension = null;
    String commentServer = null;
    String userId = null;
    String threadId = null;
    BufferedReader br = new BufferedReader(new InputStreamReader(http.getInputStream()));
    while((str = br.readLine()) != null) {
        System.out.println(str);
        System.out.println();
    
        String[] responseBodyAry = str.split("&");
        for (String responseBody: responseBodyAry) {
            String[] elementAry = responseBody.split("=");
            if ("url".equals(elementAry[0])) {
                movieServer = URLDecoder.decode(elementAry[1], "UTF-8");
                String extensionChk = movieServer.substring(movieServer.indexOf("?")+1, movieServer.indexOf("?")+2);
                if ("m".equals(extensionChk)) {
                    movieExtension = ".mp4";
                } else if ("s".equals(extensionChk)) {
                    movieExtension = ".swf";
                } else {
                    movieExtension = ".flv";
                }
            }
            if ("ms".equals(elementAry[0])) {
                commentServer = URLDecoder.decode(elementAry[1], "UTF-8");
            }
            if ("user_id".equals(elementAry[0])) {
                userId = URLDecoder.decode(elementAry[1], "UTF-8");
            }
            if ("thread_id".equals(elementAry[0])) {
                threadId = URLDecoder.decode(elementAry[1], "UTF-8");
            }
        }
    }
    br.close();
    
  • レスポンスヘッダ部の取得は不要です。

【ニコニコ動画】ログイン処理

ニコニコ動画にHTTP通信でログインし、セッションを取得します。

  • HTTP通信開始

    // HTTP通信を開始する。
    URL url = new URL("https://secure.nicovideo.jp/secure/login?site=niconico");
    String params = String.format("mail=%s&password=%s", "niconico@gmail.com", "password");
    HttpsURLConnection https = (HttpsURLConnection)url.openConnection();
    
  • リクエストヘッダ部設定

    // リクエストヘッダ部を設定する。
    https.setRequestMethod("POST");
    https.setDoOutput(true);
    https.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    https.setRequestProperty("Content-Length", Integer.toString(params.length()));
    
  • リクエストボディ部設定

    // リクエストボディ部を設定する。
    PrintStream ps = new PrintStream(https.getOutputStream());
    ps.print(params);
    ps.close();
    
  • レスポンスヘッダ部取得

    // レスポンスヘッダ部を取得する。
    String userSession = null;
    Map<String, List<String>> responseHeaders = https.getHeaderFields();
    Iterator<String> responseIt = responseHeaders.keySet().iterator();
    while (responseIt.hasNext()) {
        String responseKey = responseIt.next();
        List<String> responseList = responseHeaders.get(responseKey);
        for(String reponseValue: responseList) {
            System.out.println(responseKey + ":" + reponseValue);
            if ("Set-Cookie".equals(responseKey)) {
                String[] cookieAry = reponseValue.split(";");
                for (String cookie: cookieAry) {
                    String[] userSessionAry = cookie.split("=");
                    if ("user_session".equals(userSessionAry[0]) 
                            && userSessionAry[1].indexOf("deleted") == -1) {
                        userSession = userSessionAry[1];
                    }
                }
            }
        }
    }
    
  • レスポンスヘッダは以下のように出力されます。
    HTTPステータスコードが302なので、
    Locationに指定されたニコニコ動画のトップ画面にリダイレクトしているのが分かります。

    null:HTTP/1.1 302 Found
    x-niconico-authflag:0
    x-niconico-authflag:0
    Content-Language:ja
    Date:Fri, 28 Apr 2017 13:39:03 GMT
    Content-Length:0
    Location:http://www.nicovideo.jp/
    Set-Cookie:nicosid=1111111111.1111111111; Max-Age=315360000; Expires=Mon, 26 Apr 2027 13:39:03 GMT; Path=/; Domain=.nicovideo.jp
    Set-Cookie:user_session_secure=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; Max-Age=2591999; Expires=Sun, 28 May 2017 13:39:02 GMT; Path=/; Domain=.nicovideo.jp; Secure; HTTPOnly
    Set-Cookie:user_session=user_session_22222_zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz; Max-Age=2591999; Expires=Sun, 28 May 2017 13:39:02 GMT; Path=/; Domain=.nicovideo.jp
    Set-Cookie:user_session=deleted; Max-Age=0; Expires=Fri, 28 Apr 2017 13:39:03 GMT; Path=/
    Set-Cookie:nicosid=3333333333.3333333333; expires=Mon, 26-Apr-2027 13:39:03 GMT; Max-Age=315360000; path=/; domain=.nicovideo.jp
    X-niconico-sid:3333333333.3333333333
    X-niconico-sid:4444444444.4444444444
    Connection:close
    Content-Type:text/html; charset=UTF-8
    Server:Apache
    

    取得したいのは5つある「Set-Cookie」のうち、3つ目の「user_session」の値です。
    不要:「nicosid」
    不要:「user_session_secure」
    必要:「user_session」
    不要:「user_session」(deletedのものは不要)
    不要:「nicosid」

    クッキーからセッションを取得できれば良いので
    レスポンスボディ部の取得は行いません。

【ニコニコ動画】JavaでHTTP通信

JavaでHTTP通信をお試しする上で電車検索のAPIやGoogleのAPI等、色々ありますが、
ニコニコ動画のAPIを利用してみることにしました。
まずはHTTP通信についての基礎事項を記載します。

  • HTTP通信開始
    HTTP通信を利用するには抽象クラスであるURLConnectionクラスを利用します。

    // HTTP通信接続
    URL url = new URL("http://xxx");
    HttpURLConnection httpUrlConnection = (HttpURLConnection)(url.openConnection());
    
    // HTTPS通信接続
    URL url = new URL("https://xxx");
    HttpsURLConnection httpsUrlConnection = (HttpsURLConnection)(url.openConnection());
    

    上記だけではまだサーバへの接続は開始されておらず、
    接続管理オブジェクトが生成された状態で、
    後述の「httpUrlConnection.getOutputStream()」か
    「httpUrlConnection.getInputStream()」が呼び出されると、
    内部的に「httpUrlConnection.connect()」が呼び出されます。
    切断メソッドはなく、「httpUrlConnection.getInputStream()」で取得した
    「InputStream」がcloseされるとサーバから切断されます。

  • POST通信とGET通信
    POST通信、またはGET通信を行う設定は以下の通りです。

    // POST通信
    httpUrlConnection.setRequestMethod("POST");
    httpUrlConnection.setDoOutput(true);
    
    // GET通信
    httpUrlConnection.setRequestMethod("GET");
    
  • リクエストヘッダ部の設定
    リクエストヘッダ部に値を設定する場合は以下の通りです。

    // リクエストヘッダ部設定
    httpUrlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    
  • リクエストボディ部の設定
    リクエストボディ部に値を設定する場合は以下の通りです。
    しかし、GET通信の場合、リクエストボディ部は設定しないのが正しいです。
    パラメタは「http://xxx?mail=xxxx.yyyy.zzzz@gmail.com&password=pass」で渡します。

    // リクエストボディ部に設定するパラメータ
    String params = String.format("mail=%s&password=%s", "xxxx.yyyy.zzzz@gmail.com", "pass");
    // リクエストボディ部設定
    PrintStream out = new PrintStream(httpUrlConnection.getOutputStream());
    out.print(params);
    out.close();
    
  • レスポンスボディ部の取得
    レスポンスボディ部を取得する場合は以下の通りです。

    BufferedReader responseBody = new BufferedReader(new InputStreamReader(httpUrlConnection.getInputStream()));
    String str = null;
    while((str = responseBody.readLine()) != null) {
        System.out.println(str);
    }
    responseBody.close();
    
  • レスポンスヘッダ部の取得
    レスポンスヘッダ部を取得する場合は以下の通りです。

    Map<String, List<String>> responseHeaders = https.getHeaderFields();
    Iterator<String> responseIt = responseHeaders.keySet().iterator();
    while (responseIt.hasNext()) {
        String responseKey = responseIt.next();
        List<String> responseList = responseHeaders.get(responseKey);
        for(String reponseValue: responseList) {
            System.out.println(responseKey + ":" + reponseValue);
        }
    }
    

【Excel】CSVファイルを開くその2

  • 改行ありのテキストファイルを読み取り
    ツールバーの「データ」-「外部データの取り込み」-「テキストファイル」から読み取る方法では、
    項目内に改行があるとずれたり、
    行数が多いと最後まで読み取れないことがある。

    そこで、セル全体を文字列に設定しておき、
    1セルを選択し、適当な文字列を入力する。
    次にそのセルを選択し、ツールバーの「データ」-「区切り位置」を選択する。
    「カンマやタブなどの区切り文字によってフィールドごとに区切られたデータ」を選択する。
    区切り文字に「カンマ」を選択する。
    列のデータ形式に「文字列」を選択する。

    最後にテキストファイルをCTRL+Aで全選択後にコピーし、
    先ほどのセルに貼りつけると、項目内に改行があってもずれずに
    行数が多くても貼りつけることができる。