Help us understand the problem. What is going on with this article?

YouTube Data api v3をPythonから使って特定のチャンネルの動画を取得する

何をするか

タイトルの通り、YouTube Data api v3を利用して、特定のチャンネルの動画を取得します。
なお、参考記事に書かれているpublishedAfter等のパラメータをいじってまで全部の動画を取得はしません。
あるチャンネルの動画を500件くらい欲しいなーと思った時があったので作りました。

API_KEYはgoogle developer consoleから取得し、環境変数にいれて使用します。
取得の方法についてはgoogle - 承認の認証情報を取得するを参照してください。
(Oauthトークンを取得する必要はありません)

チャンネルIDについて

ブラウザからチャンネルのページに遷移し、https://www.youtube.com/channel/XXXXXXXXXXXXの部分を取得するのがほぼ間違いなく楽だと思うのですが、一応スクリプトも置いておきます。
スクリプトを使えば、検索クエリでのチャンネルの一括検索のようなことができるので、そういう用途であれば使い勝手がいいかもしれません。

  • apiclient(pip install --upgrade google-api-python-clientで取得)
  • easydict(pip install easydictで取得)

の2つを使用していますが、後者はデフォルトで入っているargparseで代用可能です(というよりもargparseが主流です)

import os
from easydict import EasyDict as edict
from apiclient.discovery import build
from apiclient.errors import HttpError

API_KEY = os.environ['API_KEY']
API_SERVICE_NAME = "youtube"
API_VERSION = "v3"

youtube = build(API_SERVICE_NAME, API_VERSION, developerKey=API_KEY)

opt = edict()
opt.q = 'ここに検索したいワードを入れる'
opt.max_results = 25

search_response = youtube.search().list(
    q=opt.q,
    part="id,snippet",
    maxResults=opt.max_results
).execute()

channels = []

for search_result in search_response.get("items", []):
    if search_result["id"]["kind"] == "youtube#channel":
        channels.append("%s (%s)" % (search_result["snippet"]["title"],
                                   search_result["id"]["channelId"]))

print("Channels:\n", "\n".join(channels), "\n")

チャンネルの動画を取得する

本題ですが、googleが提供しているapiclientに含まれているsearch.listメソッドを使用しての取得に手間取りました。
そのため、StackOverflow - YouTube API to fetch all videos on a channel を参考にしてrequestsから直接リクエストを送るようにしています。

import os
import time
import requests

import pandas as pd


API_KEY = os.environ['API_KEY']
CHANNEL_ID = 'your_searching_channel_id'

base_url = 'https://www.googleapis.com/youtube/v3'
url = base_url + '/search?key=%s&channelId=%s&part=snippet,id&order=date&maxResults=50'
infos = []

while True:
    time.sleep(30)
    response = requests.get(url % (API_KEY, CHANNEL_ID))
    if response.status_code != 200:
        print('エラーで終わり')
        break
    result = response.json()
    infos.extend([
        [item['id']['videoId'], item['snippet']['title'], item['snippet']['description'], item['snippet']['publishedAt']]
        for item in result['items'] if item['id']['kind'] == 'youtube#video'
    ])

    if 'nextPageToken' in result.keys():
        if 'pageToken' in url:
            url = url.split('&pageToken')[0]
        url += f'&pageToken={result["nextPageToken"]}'
    else:
        print('正常終了')
        break

videos = pd.DataFrame(infos, columns=['videoId', 'title', 'description', 'publishedAt'])
videos.to_csv('videos.csv', index=None)

これで、動画のidとタイトル、説明文と投稿日のcsvファイルを吐き出すことができます。

参考

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away