Python プログラミング

【Python】Youtubeの動画コメントをAPI経由で全件取得する

この記事は約9分で読めます。

 

 

こんにちは、ミナピピン(@python_mllover)です。今回はMENTAでYoutubeの特定の動画に紐づいているコメントを全件取得してほしいという依頼を受けたので調べた結果をまとめておこうかなと思います。

 

関連記事:【Python】YoutubeのAPIを叩いて色んな動画情報を取得してみる

 

まず結論からいうとYoutubeのコメントは数千件を取得するのが限界で数万件のコメントを取得するのはAPIの仕様上不可能だと思われます。

 

基本的に動画のコメントは1回のAPIアクセスにつき、100件を上限に取得することができます。加えてAPIのレスポンスに含まれているnextPageTokenを使用することで、100件×20回の合計2000件取得することが可能です。

 

これはコメントスレッド(親コメント)の上限数で、これらにコメントに返信がついている場合、その2000件に紐づいている返信(子コメント)も取得することができ、親コメントと子コメントを合わせて合計で~6000件くらい取得することができます。

 

以下がそのコードになります。

 

# ライブラリの読み込み
import pandas as pd
import requests
from typing import Dict
import requests
import json

URL = 'https://www.googleapis.com/youtube/v3/'
API_KEY = '自分のAPI鍵'

# 1つ目の動画のコメント情報を取得
VIDEO_ID = 'コメントを取得したいID'


def print_video_comment(no, video_id, next_page_token, text_data):
    params = {
      'key': API_KEY,
      'part': 'snippet',
      'videoId': video_id,
      'order': 'relevance',
      'textFormat': 'plaintext',
      'maxResults': 100,
    }
    if next_page_token is not None:
        params['pageToken'] = next_page_token
    response = requests.get(URL + 'commentThreads', params=params)
    resource = response.json()

    for comment_info in resource['items']:
        # コメント
        text = comment_info['snippet']['topLevelComment']['snippet']['textDisplay']
        # グッド数
        like_cnt = comment_info['snippet']['topLevelComment']['snippet']['likeCount']
        # 返信数
        reply_cnt = comment_info['snippet']['totalReplyCount']
        # ユーザー名
        user_name = comment_info['snippet']['topLevelComment']['snippet']['authorDisplayName']
        # Id
        parentId = comment_info['snippet']['topLevelComment']['id']
        # ユーザープロフィール情報
        author_channel = comment_info["snippet"]['topLevelComment']['snippet']['authorChannelUrl']
        # リストに取得した情報を追加
        text_data.append([parentId, 'parent', text, like_cnt, reply_cnt, user_name, author_channel])
        # 処理確認用
        if len(text_data) % 100 == 0:
            print(len(text_data))
#     print('{:0=4}\t{}\t{}\t{}\t{}'.format(no, text.replace('\n', ' '), like_cnt, user_name, reply_cnt))
        if reply_cnt > 0:
            cno = 1
            print_video_reply(no, cno, video_id, next_page_token, parentId, text_data)
        no = no + 1

    if 'nextPageToken' in resource:
        print_video_comment(no, video_id, resource["nextPageToken"], text_data)
        

def print_video_reply(no, cno, video_id, next_page_token, id, text_data):
    params = {
      'key': API_KEY,
      'part': 'snippet',
      'videoId': video_id,
      'textFormat': 'plaintext',
      'maxResults': 50,
      'parentId': id,
      }

    if next_page_token is not None:
        params['pageToken'] = next_page_token
    response = requests.get(URL + 'comments', params=params)
    resource = response.json()

    for comment_info in resource['items']:
        # コメント
        text = comment_info['snippet']['textDisplay']
        # グッド数
        like_cnt = comment_info['snippet']['likeCount']
        # ユーザー名
        user_name = comment_info['snippet']['authorDisplayName']
        # ユーザープロフィール情報
        author_channel = comment_info["snippet"]['authorChannelUrl']
        # リストに取得した情報を追加
        text_data.append([id, 'child', text, like_cnt, 0, user_name, author_channel])
#       print('{:0=4}-{:0=3}\t{}\t{}\t{}'.format(no, cno, text.replace('\n', ' '), like_cnt, user_name))
        cno = cno + 1

    if 'nextPageToken' in resource:
        print_video_reply(no, cno, video_id, resource["nextPageToken"], id, text_data)

text_data=[]
# コメントを全取得する
video_id = VIDEO_ID
no = 1
# 取得処理を実行
print_video_comment(no, video_id, None, text_data)
# データフレーム作成(高評価順にソート)
df = pd.DataFrame(text_data, columns=['comment_id', 'type', 'comment_data', 'like_cnt', 'reply_cnt', 'user_name', 'profile_page']).sort_values('like_cnt', ascending=False)
# csv出力
df.to_csv(str(movie_data.title[2])+'.csv', index=False)
# データフレームを一部出力して確認する
df.head()

 

<実行結果>

 

 

YoutubeのAPIの基本的な叩き方は別の記事で解説しているので、そちらを参考にしてください。

 

今回のコードのミソとしてはまずprint_video_comment()でコメント取得のAPIを一回叩くことで最大100件のコメントを取得することができます。100件以上ある場合は[“nextPageToken”]もAPIレスポンスで返されてくるので、それを使い&pageToken=にその値を入れてURLに付与することにより100件より先のコメントの続きを取得ことができます。

また、これで取得したコメントは親コメントと言われる部類のもので、それに返信があった場合、返信コメント(子コメント)が存在してます。[“totalReplyCount”]が1以上であれば子コメントが存在するので、print_video_reply()で取得する処理を行っています。件数が多い場合は先ほどと同じくpageTokenを使いできるかぎり取得しています。

 

コメントが数万件ある場合でも全件取得できる方法がもしありましたらツイッターやコメント欄などで教えていただけると幸いです。では~

 

参照:http://sleepyokayu.blogspot.com/2018/04/youtube_12.html

参照:https://qiita.com/yaju/items/3bec88dbd544502e1343

 

 

 

 

コメント

  1. […] 関連記事:【Python】Youtubeの動画コメントをAPI経由で全件取得する […]

  2. […] 関連記事:【Python】Youtubeの動画コメントをAPI経由で全件取得する […]

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