カタバミさんのプログラミングノート

日曜プログラマーがプログラミング関係のメモを記録するブログです。

VB 2013でニコニコ動画にログイン――ついでにgetflv APIを呼び出す

これまでの投稿ではRuby 2.0.0でニコニコ動画APIを使おうと奮闘していましたが、初心に帰ってC++VBでも同じことをしてみたかったので実行してみました。この投稿ではライブラリが揃っていてサクサク作れたVisual Basic 2013から。C#ではいくつも作られているようなので二番煎じ感は拭えませんが――

最初にコードを示します。開発環境のMicrosoft Visual Studio Express 2013 for Windows Desktopではコンソールアプリケーションのプロジェクトで実行できています。例外処理等はスキップしているので注意して下さい。

Imports System.Net
Imports System.IO
Imports System.Text

Module Module1
    Sub Main()
        Dim cc As CookieContainer = NicoVideoAPI.Login(メールアドレス, パスワード)

        'マイページのHTMLを取得する
        Console.WriteLine("■マイページのHTML")
        Console.WriteLine(NicoVideoAPI.Read(cc, "http://www.nicovideo.jp/my/top"))
        Console.WriteLine()

        'getflv APIで組曲「ニコニコ動画」の動画保存場所を取得する
        Console.WriteLine("■getflv API")
        Console.WriteLine(NicoVideoAPI.Read(cc, "http://flapi.nicovideo.jp/api/getflv/sm500873"))
        Console.WriteLine()
    End Sub
End Module

Namespace NicoVideoAPI
    Public Module NicoVideoAPI
        'ニコニコ動画にログインして会員ページに必要なクッキーを返します。
        Public Function Login(ByVal Mail As String, ByVal Password As String) As CookieContainer
            'データをPOSTする
            Dim content As String = "mail=" & Mail & "&password=" & Password
            Dim contentBytes As Byte() = Encoding.ASCII.GetBytes(content)
            Dim request As HttpWebRequest = HttpWebRequest.CreateHttp(
                "https://secure.nicovideo.jp/secure/login?site=niconico")
            request.CookieContainer = New CookieContainer
            request.Method = "POST"
            request.ContentType = "application/x-www-form-urlencoded"
            request.ContentLength = contentBytes.Length
            Using stream As Stream = request.GetRequestStream()
                stream.Write(contentBytes, 0, contentBytes.Length)
            End Using

            '応答を確認してcookieを取得する
            Using response As HttpWebResponse = request.GetResponse()
                Return request.CookieContainer
            End Using
        End Function

        'GETを送信してHTML、XML等を取得します。
        Public Function Read(ByRef cc As CookieContainer, ByVal URL As String) As String
            Dim request As HttpWebRequest = HttpWebRequest.CreateHttp(URL)
            request.CookieContainer = cc
            Using response As HttpWebResponse = request.GetResponse()
                Using reader As New StreamReader(response.GetResponseStream())
                    Return reader.ReadToEnd
                End Using
            End Using
        End Function
    End Module
End Namespace

コードを実行するとマイページのHTMLと組曲ニコニコ動画」のgetflv APIの戻り値が順に出力されます。

NicoVideoAPIモジュールのLoginメソッドはニコニコ動画へのログイン、ReadメソッドはGETを送信してHTML、XML等の取得を行います。Loginメソッドでのログインに失敗していればサンプルコードで最初に呼び出したReadメソッド(マイページのHTMLを取得する)はログインページのHTMLを返します。成功していればマイページのHTMLを返します。次のReadメソッドは(getflv APIの呼び出し)は成功・失敗に関わらずプレーンテキストを返しますが、失敗時は淡白なコードを返します。

Loginメソッドの中ではHttpWebRequestを作ってログインページにメールアドレスとパスワードをPOST、HttpWebResponseで応答を取得してCookieContainerにRubyではset-cookieだった値を格納しています。以降はHttpWebRequestにCookieContainerを指定してGETするだけで会員ページのHTMLを取得することができます。

実際にGETを行うのはReadメソッドの役割です。VB 2013ではクッキーの扱いをCookieContainerとHttpWebRequestが受け持ってくれるので素直に任せています。

ちなみにContentTypeでapplication/x-www-form-urlencodedを指定しているので本当はエンコードしないといけないのでしょうが、メールアドレスとパスワードにエンコードの必要そうな文字は含まれないだろうからここでは無視しています。

C++版がないのはVS 2013ではOpenSSLのバージョン違いでBoost.Asioが使えなかった為です。公式ページからソースコードを落とそうとしたら、どのミラーにも拒否られました。拒否されなくなったら、そのうち書いてみたいと思います。