はじめに
Youtube API でチャンネル内の動画を取得したいということがよくあります。
しかしながら、まとまった記事が見当たらなかったので書いておきます。
基本的なこと
Youtube API はいずれの機能も1ページに最大で50項目までしか返さない仕様となっています。
そのため、まず maxResults で1ページの項目数を最大値の 50 に設定し、結果にある nextPageToken を使用して2ページ目、3ページ目を取得していくという構成になります。
1ページ目:
https://www.googleapis.com/youtube/v3/playlistItems?part=id,snippet,contentDetails,status&playlistId=UUutJqz56653xV2wwSvut_hQ&maxResults=50
{
"kind": "youtube#playlistItemListResponse",
"etag": "5wQJ8S-f8gfei4RZAm0-c6iHnzU",
"nextPageToken": "CAUQAA",
"items": [
{
2ページ目:
https://www.googleapis.com/youtube/v3/playlistItems?part=id,snippet,contentDetails,status&playlistId=UUutJqz56653xV2wwSvut_hQ&maxResults=50&&pageToken=CAUQAA
また、記事内のURLは全てAPIkeyを削除したものとなっていますので、必要に応じて書き換え・読み替えてください。
パターン1
1つ目はBADパターンです。
しかし、広く知られた方法であり、この方法を使用している記事は非常に多いです。
念のため紹介しておきます。
それは、search のエンドポイントを使用して、検索条件にチャンネルIDを指定して動画を取得する方法になります。
この方法は一見うまくいくように見えるのですが、/search は nextPageToken を10ページまでしか返さない問題があります。(バグ?)
つまり、50 項目 x 10 ページ = 合計500項目までしか返せません。
そのため、古参YouTuberやショート動画メインなど動画数の多いチャンネルの場合は全ての動画を取得できない状態となっていしまします。
この対策は、publishedAfter と publishedBefore を使用して期間を指定する方法になり、かなり手間がかかってしまいます。
日本語の記事だとこのあたりでしょうか。
また、seach の API はコストが高いため、後述する方法に比べてコストが高くなる問題もあります。
一方で、search API は自由度が高いため、order で並び替えられるのがメリットです。
再生数順などに並び替えられるため、そういった使い方をする場合は、search を使う方法も良いかもしれません。
パターン2
これがお勧めの方法です。
channel API でチャンネル内のデータを取得すると、uploads の項目があります。
channel API の contentDetails の項目内にあります。
https://www.googleapis.com/youtube/v3/channels?part=id,contentDetails&id=UCM3yhFc0-fBFuvqx1Vg2YNQ
"contentDetails": {
"relatedPlaylists": {
"likes": "",
"favorites": "",
"uploads": "UUM3yhFc0-fBFuvqx1Vg2YNQ"
}
},
※ このプレイリストは、チャンネルID の 冒頭 UC を UU に書き換えても取得できると思います。
この uploads の項目にはアップロード済の動画プレイリストが設定してあり、playlistitem API を使用することで動画一覧を取得できます。
この情報があまり知られていない理由は、uploads のプレイリストが公式のドキュメントで説明されていないことが理由だと思います。
プレイリストのIDを取得したら、プレイリストの項目を取得していくだけです。
プレイリストの場合は、searchと異なり、10ページの制限が無いため全ての動画を取得できます。
https://www.googleapis.com/youtube/v3/playlistItems?part=id,snippet,contentDetails,status&playlistId=UUutJqz56653xV2wwSvut_hQ
コード例(Node):
let nextPageToken = ""
const maxResults = 50
const playlistId = "UUM3yhFc0-fBFuvqx1Vg2YNQ"
while (nextPageToken != null) {
url = 'https://www.googleapis.com/youtube/v3/playlistItems?part=id,contentDetails&playlistId=' + playlistId + '&key=' + YOUTUBE_API_KEY + '&maxResults=' + maxResults + '&pageToken=' + nextPageToken
jsonFull = await http_get(url) //http get
console.log(jsonFull)
if (jsonFull["nextPageToken"])
nextPageToken = jsonFull["nextPageToken"]
else
nextPageToken = null
}
これで問題なく取得できるはずです。
参考になりましたら幸いです。
コメント