Python 「YouTube Data API」キーワード検索により動画チャンネルのランキングを作成する

 本記事では、下図のようにURL、チャンネルタイトル、動画タイトル、閲覧数、いいね数などを抽出してcsvファイルに保存する雛形コードを載せました。APIキーは次のリンク先で取得できます。OAuth 2.0 トークンは不要です。https://console.developers.google.com

f:id:HK29:20201010030025p:plain

 そして、動画チャンネルの視聴数ランキング結果を横棒グラフで作成します。下図は「python」「自動化」というキーワードで検索した結果です。(最近、実践動画を出しまくってるキノコードさんがダントツ一位です。個人的には想定内の結果)

f:id:HK29:20201010030802p:plain

■本プログラム
Jupyter Labで動作確認をしています。次の1から5を順にセルで実行してゆきます。

1. 検索してデータを抽出するコード

from googleapiclient.discovery import build
import pandas as pd

def get_video_info(query, maxResults, next):
    search_request = youtube.search().list(
        part='id',
        q=query,
        type='video',
        maxResults=maxResults,
    )
    
    i = 0
    while search_request and i < next:
        search_response = search_request.execute()
        video_ids = [item['id']['videoId'] for item in search_response['items']]

        videos_response = youtube.videos().list(
            part='snippet,statistics',
            id=','.join(video_ids)
        ).execute()

        yield videos_response['items']
        # list_nextメソッドで次の検索へ進む
        search_request = youtube.search().list_next(search_request, search_response)
        i += 1

    return search_request
    
YOUTUBE_API_KEY = 'APIキー'
youtube = build('youtube', 'v3', developerKey=YOUTUBE_API_KEY)
query = 'python,自動化' #検索キーワード。ANDは「/」「,」 NOTは「-」 ORは「|」
dict = get_video_info(
    query,
    50, #1回あたりの検索数。最大は50
    3, #取得回数。50以上の場合に2以上が有効
)

2. データをcsvファイルに保存するコード

import codecs
# csvファイルに保存する
extacted_data_file = 'xxx_viewCount_ranking.csv'
with codecs.open(extacted_data_file, "w", encoding='cp932', errors='replace') as f:
    for i, items_per_page in enumerate(dict):
        if i == 0:
            column_list = ['id', 'url',
                           'publishedAt','channelTitle', 'channelId', 'title',
                           'viewCount', 'likeCount', 'dislikeCount', 'favoriteCount', 'commentCount']
            column_list_str = ','.join(column_list)
            f.write(column_list_str + '\n')
        for item in items_per_page:
            dic_list = []
            dic_list.append(item['id'])
            dic_list.append('http://youtube.com/watch?v=' + item['id'])
            # snippet オブジェクトには、タイトル、説明、カテゴリなどが格納されている。
            snippet = item['snippet']
            for key in ['publishedAt', 'channelTitle','channelId','title']:
                dic_list.append(snippet[key].replace(',', '_'))
            # statistics オブジェクトには、動画に関する統計情報が格納されている。
            statistics = item['statistics']
            for key in ['viewCount','likeCount','dislikeCount','favoriteCount','commentCount']:
                dic_list.append(statistics[key] if key in statistics else "NA")               
            f.write(','.join(list(map(str, dic_list))) + '\n')

3. pandasデータフレーム型で読み出すコード

df = pd.read_csv(extacted_data_file, encoding='cp932')
# 型を一応確認する
display(df.dtypes) df.tail(5)

参考までに、抽出したデータの型は次の通りです。

f:id:HK29:20201010025646p:plain

4. 動画チャンネルのランキングを作成するコード

### チャンネルランキングを作成する
# 列の合計を取得する。型はpandasのSeries型になる
s = df.groupby(['channelTitle'])['viewCount'].agg('sum')
# 並び替える
s.sort_values(ascending = False, inplace=True)
display(s)
s.to_csv('xxx_channelTitle_ranking.csv', sep=',', encoding='cp932', errors='replace')

5. ランキング結果を横棒グラフ化するコード

import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
# 横棒グラフ化の関数
def xy_plot(df, X, Y):
    df.sort_values([Y], ascending = True, inplace=True)
    df_x = df.tail(30)[X] # ベスト30を抽出
    df_y = df.tail(30)[Y]
    
    y_np = np.array(df_y)
    plt.figure(figsize=(8,10))
    plt.barh(range(len(df_x)), df_y, tick_label=df_x, align="center", color="magenta", height=0.8)
    for i, j in enumerate(y_np):
        plt.text(j, (i+0.5), str(int(j)), ha='left', va='top')
    #plt.title()
    plt.xlabel('count', fontsize=10)
    #if range_X:
    #    plt.xlim([range_X[0], range_X[1]])
    plt.grid(which="major", axis="x", color="black", alpha=0.8, linestyle="-", linewidth=1)
    plt.tight_layout()
    plt.show()
    #fig_name = "bar.png"
    #plt.savefig(fig_name)

DF = s.reset_index(inplace=False)
display(DF)
xy_plot(DF, 'channelTitle', 'viewCount')

(参考)APIの Quotas が使用上限に達したら403エラーが表示されます。日を改めれば再び実行できるようになります。

以上

<広告>