Djangoアプリでニコニコ動画のAPI getthumbinfo を使って動画IDから動画のタイトルや説明文といったメタ情報を取得してみましょう。
※getthumbinfo は存在自体が運営から公開されているわけではありませんが、存在が確認されている非公開APIです。存在自体が非公開なので使っていいともダメとも言われていないものなので、いつでも変更されたり、使えなくなるリスクがあります。利用は自己責任で。
目次
モデル
今回はゆっくり村での実装ついでの備忘がメインです。
動画ID自体は予めデータベースに登録されており、モデルは次のようになっているとします。
class Article(models.Model): # 省略 movie_id = models.CharField(max_length=50) # 省略
つまり {{ article.movie_id }} で動画IDが取得可能な状態だとします。
ビュー
投稿詳細ページで動画のタイトルを表示したいとします。
from . import get_data_api class DetailView(generic.DetailView): model = Article template_name = 'moviebbs/detail.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) self.object = self.get_object() # 動画のメタ情報 movie_id = self.object.movie_id movie_platform = self.object.movie_platform movie_meta = get_data_api.get_movie_meta(movie_id, movie_platform) context['movie_title'] = movie_meta['movie_title'] context['channeltitle'] = movie_meta['channeltitle'] return context
投稿詳細ページのビュー(今回はDetailView)の中で get_context_data() で元のコンテキストデータを取得し、動画のメタデータを取得するための関数(今回はget_data_api.pyファイルにget_movie_meta関数を用意しました)の引数として movie_id を渡します。
ゆっくり村ではニコニコ動画だけではなくYouTubeにも対応しているため movie_platform も渡していますが、この記事のテーマとは関係ないのでスルーしてください。
get_data_api.py
APIから動画のデータを取得するためにオリジナルファイル get_data_api.py を作成しました。
この中で動画のメタデータを取得するための関数 get_movie_meta を定義して次のように記述します。
import requests from xml.etree import ElementTree def get_movie_meta(movie_id, movie_platform): if movie_platform == "youtube": youtube = build(YOUTUBE_API_SERVICE_NAME, 'v3', developerKey = YOUTUBE_API_KEY) videos_response = youtube.videos().list(part='snippet,statistics', id='{},'.format(movie_id)).execute() # snippet snippetInfo = videos_response["items"][0]["snippet"] # 動画タイトル movie_title = snippetInfo['title'] # チャンネル名 channeltitle = snippetInfo['channelTitle'] elif movie_platform == "niconico": url = f'http://ext.nicovideo.jp/api/getthumbinfo/{movie_id}' response = requests.get(url) tree = ElementTree.fromstring(response.content) status = tree.attrib['status'] if status is not None and status == 'ok': movie_title_element = tree.find('./thumb/title') channeltitle_element = tree.find('./thumb/user_nickname') movie_title = movie_title_element.text if movie_title_element is not None else "Error: Could not retrieve video title" channeltitle = channeltitle_element.text if channeltitle_element is not None else "Error: Could not retrieve channel title" else: movie_title = "Error: Could not retrieve video title" channeltitle = "Error: Could not retrieve channel title" else: movie_title = "Unknown Title" channeltitle = "Unknown Channel" movie_meta = { 'movie_title': movie_title, 'channeltitle': channeltitle, } return movie_meta
こちらもYouTubeの場合とで分岐していますがそこは割愛します。
15行目から28行目が動画のプラットフォームがニコニコ動画の場合の処理です。
16-17行目で movie_id を getthumbinfo API に投げてデータを取得。getthumbinfo にはいわゆるAPIキーは不要でそのまま使えます。
getthumbinfo API は動画情報をXML形式で取得します。そこで18行目でPythonの標準ライブラリの一部、ElementTree.fromstring関数でXML形式の文字列を解析し、ElementTreeモジュールで扱えるオブジェクトに変換しています。
そして22-23行目で動画のタイトルと投稿者名を変数に格納しています。
同じ要領で動画の簡単なメタ情報を取得することができます。
項目名 | 説明 | 例 |
---|---|---|
./thumb/video_id | 動画ID | sm500873 |
./thumb/title | 動画タイトル | 組曲『ニコニコ動画』 |
./thumb/description | 動画説明文 | 700万再生、ありがとうございました…(以下省略) |
./thumb/thumbnail_url | 動画サムネイルのURL | https://nicovideo.cdn.nimg.jp/thumbnails/500873/500873 |
./thumb/first_retrieve | 投稿日時 | 2007-06-23T18:27:06+09:00 |
./thumb/length | 動画の再生時間 | 10:48 |
./thumb/movie_type | 動画の形式(flv,mp4,swf) | flv |
./thumb/size_high | 動画サイズ(byte) | 40007472 |
./thumb/size_low | 低画質時の動画サイズ(byte) | 35192581 |
./thumb/view_counter | 再生数 | 11831754 |
./thumb/comment_num | コメント数 | 4920095 |
./thumb/mylist_counter | マイリスト数 | 155571 |
./thumb/last_res_body | 直近のコメント | 目指せ500万コメント なう(2022/10/20 07:56:40) ( ゚∀゚)o彡゜えーりん! とかちつくちて きしめえええええええ |
./thumb/watch_url | 視聴URL | https://www.nicovideo.jp/watch/sm500873 |
./thumb/thumb_type | 固定video | video |
./thumb/embeddable | 外部プレイヤーで再生可能か(0=不可能,1=可能) | 1 |
./thumb/no_live_play | ニコ生で再生禁止か(0=可能,1=禁止) | 0 |
./thumb/tags | 設定されているタグのリスト | domain属性で国が指定(jpのみ) |
./thumb/genre | ジャンル名 | 音楽・サウンド |
./thumb/user_id | 投稿者のユーザーID | 145217 |
./thumb/user_nickname | 投稿者の名前 | しも |
./thumb/user_icon_url | 投稿者のアイコンのURL | https://secure-dcdn.cdn.nimg.jp/nicoaccount/usericon/defaults/blank_s.jpg |
そして33-36行目でこれらのデータを movie_meta という辞書データとして context に追加し、38行目でテンプレートファイルに渡しています。
テンプレート
あとはテンプレート側でコンテキストデータを呼び出すだけです。
<h1>{{ movie_title }}</h1> <p>{{ channeltitle }}</p> <div class="card mb-4"> . . .
こんな感じですね。