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

# はじめに
この投稿は、[品川アドベントカレンダー2019](https://qiita.com/advent-calendar/2019/shinagawa) 12日目です。

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

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

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

しかし、もともとやりたかったアニメの動画を指定してもうまく動かない。
相当昔の記事ですが[この辺の記事](https://s01149ht.hatenadiary.org/entry/20091216/1260983794)によるとどうやら取得の仕方が違うらしいことが判明。

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

## 普通の動画の場合
```plantuml
クライアント->ニコニコ動画:動画情報を取得
activate クライアント
activate ニコニコ動画
ニコニコ動画-->クライアント:パラメータたくさん返す
クライアント->ニコニコ動画:POST [コメント取得エンドポイント] \nBODYにthread情報
ニコニコ動画-->クライアント:コメントのXMLファイル
deactivate ニコニコ動画
deactivate クライアント
```
[![alt](http://www.plantuml.com/plantuml/svg/SoWkIImgAStDuNhSjFvnyyh7JKiUDorwtBpvSNE7hjtZvkx7JPiXvDFkgS-dxBQ2KC-QMvyksFYuQTBJ_cbFzqtdIamkoInBB4bLm3G58OTf6XUcaAwk7QOPLe-R9uA4cXS-Rjxpk6d_uyRvZnlx7pTEVTmq-SN-AOyRPnBh_03_u125QB3eGeWoY0yUDwq0SpiVDyy56WAHYbM8oNFoTubytBYw9ACeDJ45ucsYNOripUF6TH6-Fe-RWKvU2BPWDLTAAfwW0ShY2rI7rBmKOAm10000)](http://www.plantuml.com/plantuml/svg/SoWkIImgAStDuNhSjFvnyyh7JKiUDorwtBpvSNE7hjtZvkx7JPiXvDFkgS-dxBQ2KC-QMvyksFYuQTBJ_cbFzqtdIamkoInBB4bLm3G58OTf6XUcaAwk7QOPLe-R9uA4cXS-Rjxpk6d_uyRvZnlx7pTEVTmq-SN-AOyRPnBh_03_u125QB3eGeWoY0yUDwq0SpiVDyy56WAHYbM8oNFoTubytBYw9ACeDJ45ucsYNOripUF6TH6-Fe-RWKvU2BPWDLTAAfwW0ShY2rI7rBmKOAm10000)

## 公式チャンネルの場合
```plantuml
クライアント->ニコニコ動画:動画情報を取得
activate クライアント
activate ニコニコ動画
ニコニコ動画-->クライアント:パラメータたくさん返す
クライアント->ニコニコ動画:GET /api/getthreadkey?thread={thread_id}
ニコニコ動画-->クライアント:threadkey=[スレッドキー]&force_184=1
クライアント->ニコニコ動画:POST [コメント取得エンドポイント] \nBODYにthread情報とスレッドキー、force_184、user_idを追加
ニコニコ動画-->クライアント:コメントのXMLファイル
```
[![alt](http://www.plantuml.com/plantuml/svg/SoWkIImgAStDuNhSjFvnyyh7JKiUDorwtBpvSNE7hjtZvkx7JPiXvDFkgS-dxBQ2KC-QMvyksFYuQTBJ_cbFzqtdIamkoInBB4bLm3G58OTf6XUcaAwk7QOPLe-R9uA4cXS-Rjxpk6d_uyRvZnlx7pTEVTmq-SN-AOyRPnBhV7VN40Nzn89C_VJKafACejJ4bEpKIdi8oxOQGiTdfjGIxJAu8RRHZvjsFcvUyxYv-N5pv-EcjK2dnggbvHSbfyORMfZO6XBhn03_u125QB3eGeWoI20_Rbe1v8BCRfuBD0GY5QiGa-VaxnBvk74rn2NGc6bSWUcQnmsDSES0sQN5gKL0hm8ZySN-lK-x5X3jPMIdFMvS5-7hyxWP61CBmOvQpUMGcfS2J500)](http://www.plantuml.com/plantuml/svg/SoWkIImgAStDuNhSjFvnyyh7JKiUDorwtBpvSNE7hjtZvkx7JPiXvDFkgS-dxBQ2KC-QMvyksFYuQTBJ_cbFzqtdIamkoInBB4bLm3G58OTf6XUcaAwk7QOPLe-R9uA4cXS-Rjxpk6d_uyRvZnlx7pTEVTmq-SN-AOyRPnBhV7VN40Nzn89C_VJKafACejJ4bEpKIdi8oxOQGiTdfjGIxJAu8RRHZvjsFcvUyxYv-N5pv-EcjK2dnggbvHSbfyORMfZO6XBhn03_u125QB3eGeWoI20_Rbe1v8BCRfuBD0GY5QiGa-VaxnBvk74rn2NGc6bSWUcQnmsDSES0sQN5gKL0hm8ZySN-lK-x5X3jPMIdFMvS5-7hyxWP61CBmOvQpUMGcfS2J500)

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

```python
# (略)
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ドキュメント無いから辛いですね...有志の方々が一部まとめているようですが。