LoginSignup
27
30

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-09-17

何をするか

タイトルの通り、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ファイルを吐き出すことができます。

参考

27
30
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
30