OSSのライブラリをいじってニコニコ動画公式チャンネルのコメントを保存した話


はじめに

この投稿は、品川アドベントカレンダー2019 12日目です。

オレオレ実装なのでプルリクも出していません(;´・ω・)...が、せっかくなので記事にします。

1ヶ月ほど前にやった話です。
約2年前、ニコニコ動画にdアニメストア ニコニコ支店が開設されました。
配信終了になる前にコメントだけ保存して、BDで見るときにもコメントと一緒に見たいなーと思いコメントを保存するソフトウェアを探したのですが、どれもしっくりこなかったので自分で作って(改良して)しまえ!ということで作りました。

ハマったところ

普通に一般ユーザがアップロードした動画については、フォーク元のOSSですでに機能実装済みでした。

しかし、もともとやりたかったアニメの動画を指定してもうまく動かない。
相当昔の記事ですがこの辺の記事によるとどうやら取得の仕方が違うらしいことが判明。

だいぶ略しますが、違いをシーケンス図で表してみるとこんな感じ。

普通の動画の場合

公式チャンネルの場合

公式チャンネルは一度スレッドキーを取得してから同じようにリクエストをするみたい。
コードにすると以下のようになりました。

# (略)
def download_comments(session, filename, template_params, login_user_id):
    """Download the video comments."""

    output("Downloading comments for {0}...\n".format(template_params["id"]), logging.INFO)

    filename = replace_extension(filename, "xml")

    if cmdl_opts.download_english:
        post_packet = COMMENTS_POST_EN.format(template_params["thread_id"])
    # 公式チャンネルの場合
    elif template_params['id'][:2] == 'so':
        get_threadkey = session.get(COMMENTS_API_THREADKEY.format(template_params['thread_ids']['community']))
        get_threadkey.raise_for_status()
        mc = re.compile(r"threadkey=(.*)&force_184=(.*)").search(get_threadkey.text)
        threadkey = mc.group(1)
        force_184 = mc.group(2)
        post_packet = COMMENTS_POST_JP_SO.format(template_params['thread_ids']['community'], login_user_id, threadkey, force_184)
    else:
        post_packet = COMMENTS_POST_JP.format(template_params["thread_id"])

    get_comments = session.post(COMMENTS_API, post_packet)
    get_comments.raise_for_status()
    with open(filename, "wb") as file:
        file.write(get_comments.content)
# (略)

というわけで

無事先月配信終了したガルパンアニメのコメントを取得できました。
これでBDで見るときでも横にコメントプレイヤーを並べることで視聴が楽しくなりました。やったぜ。

おわりに

  • やりたいことができるソフトが無いなら作ってしまえ!という精神は勉強にもなるのでこれからも続けていきたいものです。
  • しれっと書きましたがplantumlは説明しやすくなるのでもっと広まってほしい
  • ニコニコ動画、APIドキュメント無いから辛いですね...有志の方々が一部まとめているようですが。