PythonとYouTube Data APIを使用して特定チャンネルの動画一覧を取得

Python

趣味で開発したアプリを作成する過程で、YouTube上の特定チャンネルの動画の一覧を取得したいことがありました。 

色々と調べてみると、YouTube Data APIなるものを使用することでYouTube上のデータを取得することができるようでしたが、ピンポイントで「特定チャンネルの動画一覧を取得」する方法についてまとめられている記事が見つかりませんでしたので、この記事では備忘録として手順をまとめます。

ちなみに、本記事ではPythonでの手順をまとめますが、JavaScriptやGASで行う場合にもほぼ同手順で行うことができました。

スポンサー

YouTube Data APIのAPIキーを発行

YouTube Data APIを使用するためにはAPIキーの発行を行う必要があります。

私は既に発行済みでキャプチャを取っていなかったので、まだ取得していない場合には以下の記事の前半の手順に従ってAPIキーの発行を行います。

YouTube Data API v3 を使って YouTube 動画を検索する - Qiita
前提GCP にアカウント登録済であることを前提とします。準備GCP にアクセスします。ログインしていない場合はしてください。プロジェクトを作成まずは今回使用するプロジェクトを作成します。プロジェクトの選…

特定チャンネルの動画一覧を取得

APIキーの発行が完了したら、以下の手順で特定チャンネルの動画一覧を取得します。

  • チャンネルIDからチャンネルの全動画のプレイリストIDを取得
  • プレイリストIDからプレイリストに含まれる動画のIDを取得
  • 動画IDから動画の情報を取得
  • 動画の情報からタイトルとURLを取得

個人的に必要であったデータがタイトルとURLだけだったので上記のようにしていますが、動画の情報の中には公開日や閲覧数などの情報も含まれているので、必要に応じてデータを取得することができます。

前準備

直接YouTubeのAPIをHTTPリクエストしても良いですが、API周りがまとめられたパッケージが用意されているのでpipでインストールしておきます。

pip install google-api-python-client

インストールが完了したらプログラムの先頭部分で初期化処理を実施しておきます。
(「{API Key}」には自身のAPIキーを記載する必要があります)

from apiclient.discovery import build

API_KEY = '{API Key}'
API_VER = 'v3'

youtube = build('youtube', API_VER, developerKey=API_KEY)

以降の処理では上記で生成した「youtube」インスタンスに対して処理を実行していきます。

チャンネルIDからチャンネルの全動画のプレイリストIDを取得

YouTubeのチャンネルを認識するためのチャンネルIDから、そのチャンネルに含まれる全動画のプレイリストIDを取得します。

各チャンネルのチャンネルIDは、チャンネルページにアクセスした際のURLの末尾から取得します。

取得したチャンネルIDを使用して、「youtube.channels().list」でチャンネルの情報を取得します。

色々とデータが取得できますが、必要なのは全動画のプレイリストIDだけなので「contentDetails」→「relatedPlaylists」→「uploads」から取得したIDのみ使用します。

def getChannelPlaylistId(channel_id):
  channel = youtube.channels().list(part='snippet,contentDetails', id=channel_id).execute()
  item = channel['items'][0]
  playlist_id = item['contentDetails']['relatedPlaylists']['uploads']
  return playlist_id

上記のAPIを実行した後の「channel」には以下のデータが含まれています。
(データは「吉田製作所」様のデータを取得しています)

{
  'kind': 'youtube#channelListResponse', 
  'etag': 'IxmtMsKmlheJMS0wN7xYCGye410', 
  'pageInfo': {
    'totalResults': 1, 
    'resultsPerPage': 5
  }, 
  'items': [
    {
      'kind': 'youtube#channel', 
      'etag': 'ggy2_MM1-FxeZFhlRR689M9FAS4', 
      'id': 'UC9WJo5ZJVXMZiA5XV2jLx5Q', 
      'snippet': {
        'title': '吉田製作所', 
        'description': 'ツイッター\nhttps://twitter.com/netatank\n苦情専用のお問い合わせフォーム\nhttps://netank.net/\n\n※切り抜き動画は認めません\n※商品提供、いわゆる企業コラボ、動画広告等はすべてお断りします\n', 
        'publishedAt': '2018-03-01T13:13:19Z', 
        'thumbnails': {
          'default': {
            'url': 'https://yt3.ggpht.com/ytc/AMLnZu_oWeoDc7Skyu5ACYJ8D9LHr5j-jXbwZsFWLqjR=s88-c-k-c0x00ffffff-no-rj', 
            'width': 88, 
            'height': 88
          }, 
          'medium': {
            'url': 'https://yt3.ggpht.com/ytc/AMLnZu_oWeoDc7Skyu5ACYJ8D9LHr5j-jXbwZsFWLqjR=s240-c-k-c0x00ffffff-no-rj', 
            'width': 240, 
            'height': 240
          }, 
          'high': {
            'url': 'https://yt3.ggpht.com/ytc/AMLnZu_oWeoDc7Skyu5ACYJ8D9LHr5j-jXbwZsFWLqjR=s800-c-k-c0x00ffffff-no-rj', 
            'width': 800, 
            'height': 800
          }
        }, 
        'localized': {
          'title': '吉田製作所', 
          'description': 'ツイッター\nhttps://twitter.com/netatank\n苦情専用のお問い合わせフォーム\nhttps://netank.net/\n\n※切り抜き動画は認めません\n※商品提供、いわゆる企業コラボ、動画広告等はすべてお断りします\n'}, 
          'country': 'JP'
        }, 
        'contentDetails': {
          'relatedPlaylists': {
            'likes': '', 
            'uploads': 'UU9WJo5ZJVXMZiA5XV2jLx5Q'
          }
        }
      }
    ]
  }

プレイリストIDからプレイリストに含まれる動画のIDを取得

続いてプレイリストIDから、「youtube.playlistItems().list」でプレイリストに含まれる動画のIDを取得します。

一度に取得できるIDの数50までとなっているため、50以上の動画のIDを取得する場合には「nextPageToken」を使用して再帰します。

def getVideoIds(playlist_id, page_token):
  items_info = youtube.playlistItems().list(part='contentDetails', playlistId=playlist_id, maxResults=50, pageToken=page_token).execute()
  video_ids = list(map(lambda item: item['contentDetails']['videoId'], items_info['items']))
  if 'nextPageToken' in items_info:
    video_ids.extend(getVideoIds(playlist_id, items_info['nextPageToken']))
  return video_ids

APIを使用してデータの取得を行うのはそれなりに時間がかかるので、必要なデータ数が決まっている場合には途中で処理を中断するようにした方が良いです。

上記のAPIを実行した後の「items_info」には以下のデータが含まれています。

{
  'kind': 'youtube#playlistItemListResponse', 
  'etag': 'PL0sbGh-tgxd6ZyL9zQGMZKUvPQ', 
  'nextPageToken': 'EAAaBlBUOkNESQ', 
  'items': [
    {
      'kind': 'youtube#playlistItem', 
      'etag': 'mKgR_6I1Mvu65A1GE1XTJ0M82gc', 
      'id': 'VVU5V0pvNVpKVlhNWmlBNVhWMmpMeDVRLks4SjV5UVZlS3Nn', 
      'contentDetails': {
        'videoId': 'K8J5yQVeKsg', 
        'videoPublishedAt': '2022-09-08T08:29:36Z'
      }
    }, 
    ...
  ], 
  'pageInfo': {
    'totalResults': 470, 
    'resultsPerPage': 50
  }
}

動画IDから動画の情報を取得

続いて動画のIDから、「youtube.videos().list」で動画の情報を取得します。

動画のIDごとにAPIを実行するため少し処理に時間がかかります。

def getVideos(video_ids):
  videos = []
  for index, video_id in enumerate(video_ids):
    video_info = youtube.videos().list(part='snippet,statistics', id=video_id).execute()
    videos.extend(video_info['items'])
  return videos

上記のAPIを実行した後の「video_info」には以下のデータが含まれています。

{
  'kind': 'youtube#videoListResponse', 
  'etag': 'jHgJj15zryHf25D6ecqCPbCPL5I', 
  'items': [
    {
      'kind': 'youtube#video', 
      'etag': 'Fq1g5O2hwYxZQaKMGHVq4KdXqZA', 
      'id': 'K8J5yQVeKsg', 
      'snippet': {
        'publishedAt': '2022-09-08T08:29:36Z', 
        'channelId': 'UC9WJo5ZJVXMZiA5XV2jLx5Q', 
        'title': '【解説】新型iPhone14は「何がポンコツ」で「何がスゴイ」のか?', 
        'description': 'アップル信者(プロ)がiPhone14の何が変わったのかを1分で教えてあげます\nほめてください\n\n==ヨシダグッズ==\n吉田グッズ販売\nhttps://yoshida-ss.booth.pm/\nLINEスタンプ・着せ替え\nhttps://store.line.me/stickershop/product/7048464\nhttps://store.line.me/themeshop/author/1006059\n\n==吉田の絵==\nイラストは「あかね大佐」氏が書いてます。\nhttps://www.youtube.com/channel/UCXNZG7r7Dz74oUazrBBRUsA\n\nアマゾンのリンクはアマゾンアソシエイトリンク(広告)を使用しています', 
        'thumbnails': {
          'default': {'url': 'https://i.ytimg.com/vi/K8J5yQVeKsg/default.jpg', 'width': 120, 'height': 90}, 
          'medium': {'url': 'https://i.ytimg.com/vi/K8J5yQVeKsg/mqdefault.jpg', 'width': 320, 'height': 180}, 
          'high': {'url': 'https://i.ytimg.com/vi/K8J5yQVeKsg/hqdefault.jpg', 'width': 480, 'height': 360}}, 
          'channelTitle': '吉田製作所', 
          'tags': ['PC', 'パソコン', '自作', '自作PC', '自作パソコン', 'DIY', 'ジャンク'], 
          'categoryId': '28', 
          'liveBroadcastContent': 'none', 
          'defaultLanguage': 'ja', 
          'localized': {
            'title': '【解説】新型iPhone14は「何がポンコツ」で「何がスゴイ」のか?', 
            'description': 'アップル信者(プロ)がiPhone14の何が変わったのかを1分で教えてあげます\nほめてください\n\n==ヨシダグッズ==\n吉田グッズ販売\nhttps://yoshida-ss.booth.pm/\nLINEスタンプ・着せ替え\nhttps://store.line.me/stickershop/product/7048464\nhttps://store.line.me/themeshop/author/1006059\n\n==吉田の絵==\nイラストは「あかね大佐」氏が書いてます。\nhttps://www.youtube.com/channel/UCXNZG7r7Dz74oUazrBBRUsA\n\nアマゾンのリンクはアマゾンアソシエイトリンク(広告)を使用しています'
          }, 
          'defaultAudioLanguage': 'ja'
        }, 
        'statistics': {
          'viewCount': '965342', 
          'likeCount': '26134', 
          'favoriteCount': '0', 
          'commentCount': '1460'
        }
      }
    ], 
    'pageInfo': {
      'totalResults': 1, 
      'resultsPerPage': 1
    }
  }

ここで取得できるデータには「タイトル」や「説明文」の他に「URLの末尾情報」や「閲覧数」なども含まれているので、解析系のツールを作ろうと思ったらここからデータを取得します。

動画の情報からタイトルとURLを取得

最後にこれまで作成した処理をつなげて、取得した動画の情報から必要な情報を抽出します。

ここでは「タイトル」と「URL」を抽出していますが、他にも必要なデータがあれば抽出することはできます。

channel_id = 'UC9WJo5ZJVXMZiA5XV2jLx5Q'
playlist_id = getChannelPlaylistId(channel_id)
video_ids = getVideoIds(playlist_id, None)
videos = getVideos(video_ids)

for video in videos:
  print(video['snippet']['title'], ',', 'https://youtube.com/watch?v=' + video['id'])

上記を実行すると、少し時間を空けてから以下のような出力がされます。

【解説】新型iPhone14は「何がポンコツ」で「何がスゴイ」のか? , https://youtube.com/watch?v=K8J5yQVeKsg
【生放送】新型iPhone14発表会を一緒に視聴しよう!(リーク情報あり) , https://youtube.com/watch?v=z1ENaaOEOTQ
筋肉マッチョ集団に100万人達成を祝福されたよ【ヨツタヨツオ】 , https://youtube.com/watch?v=egs67R__3B0
世界一辛い「サドン・デスソース(死)」で唐揚げ作ったら…死んだ(´;ω;`) , https://youtube.com/watch?v=M_pSbWOVQWo
【詐欺】Amazonの「中華製ゲーミングPC(★1)」の闇を暴く【絶対に買うな】 , https://youtube.com/watch?v=TllRK5rpDvU
世界最強の酒「スピリタス96%」を飲んだ結果…これは死ぬ(´;ω;`) , https://youtube.com/watch?v=JsO_U_W2b3I
〇〇〇万円!?ガチ純金製の「黄金iPhone」を衝動買い!破産寸前ですwww , https://youtube.com/watch?v=nbR_zWAYk1E
【軍隊堅麺麭】日本陸軍の戦闘糧食「世界一固いパン」を食べてみた! , https://youtube.com/watch?v=ZbKEDe_wQB0
【世界最大】Amazonでイヤホンを買ったら...超巨大だったwww , https://youtube.com/watch?v=X8oqfo5vRbU
【欠陥住宅の闇】無断熱で灼熱地獄、電気代4万円!人間が住む家ではない!(完結編) , https://youtube.com/watch?v=_CRrQ9M7oa0
100万人YouTuberが住む「5万円の欠陥住宅」ルームツアー!!!(前編) , https://youtube.com/watch?v=BWkIh_6UI_E
破産寸前の100.0万人カウントダウン生放送!!!(開始時間は達成しそうな時間に合わせて前後します) , https://youtube.com/watch?v=UqpHJ7T1uaE
【短命覚悟】100kgデブ秘伝「世界一旨いチャーシュー」の作り方(嘘)!!!!!!!!!! , https://youtube.com/watch?v=eIvToFLq6ZQ
【15万円】韓国の折り畳めるスマホ、怒りの「逆パカ」破壊!!!!!! , https://youtube.com/watch?v=hLdtqXprGdU
【絶対買え】コスパ世界一「Google純正スマホ」が凄い!【Pixel 6a】 , https://youtube.com/watch?v=Geiw6_o6HU8
【生】1億円マイホーム完成?建築状況をコッソリ教えます , https://youtube.com/watch?v=heYDF9x14Dw
SONY最先端技術「ゲーミングヘッドセット」がヤバイ。中華品質マイク【INZONE H9】 , https://youtube.com/watch?v=GBLCHCrNVsk
何でも簡単操作「3Dプリンター」の凄さ・便利さがわかる動画! , https://youtube.com/watch?v=96SPyo6qjz4
【絶対買うな】SONYの16万円「新型ゲーミングモニター」が酷すぎる【INZONE M9】 , https://youtube.com/watch?v=achQbrlLKjQ
伝説スマホ「BALMUDA Phone」に専用ワイヤレス充電器が新登場www , https://youtube.com/watch?v=cFuZPkldyF0

あとはこれをJSONなりDBなりに出力することで必要なデータの取得が完了です。

終わりに

PythonでYouTube Data APIを使用して特定チャンネルの動画一覧を取得する方法について解説しました。

今回の記事についてわからなかった点や誤っている点などありましたらコメントまでお願いいたします。

コメント

タイトルとURLをコピーしました