Youtube Data APIを使ってPythonでYoutubeデータを取得する

#はじめに
最近、APIを用いて色々なデータを取得できないかを調べています。
Youtube Data APIを使用して動画の再生回数やいいね数などの情報取得する方法を調べて実践したので覚書的に記事にまとました。
#参考
Youtube Data APIの使用に当たって下記を参考にいたしました。

- [PythonでYoutube動画検索](https://ossyaritoori.hatenablog.com/entry/2018/01/22/Python%E3%81%A7Youtube%E5%8B%95%E7%94%BB%E6%A4%9C%E7%B4%A2)　
- [YouTube Data API の概要](https://developers.google.com/youtube/v3/getting-started?hl=ja)
- [Youtube Data API のリファレンス](https://qiita.com/Hironsan/items/513b9f93752ecee9e670)　

#APIの使用準備
##Youtube Data APIの登録
Youtube Data APIの取得にはまずGoogleアカウントが必要になります。
下記手順でYotube Data APIの登録を行い、APIキーを取得します。

- [Google Cloud Platform](https://console.developers.google.com/project)にアクセスした後新しいプロジェクトを作成
- 新たに作成したプロジェクトにチェックを入れた状態で「APIとサービス」から「ダッシュボード」に移動
- 移動後の画面から更に「APIライブラリ」に移動し検索画面から「YouTube Data API v3
」を探してその先のページへ移動
- 移動後の画面にて「YouTube Data API v3」のAPIを有効にする
- 「認証情報」の画面から「認証情報作成」のボタンを押下し、APIキーを取得

##PythonでAPIから情報を取得するためのライブラリを取得
[こちら](https://github.com/googleapis/google-api-python-client/blob/master/README.md)のライブラリを取得します。下記のようにpipでインストールが可能です。

```python
pip install google-api-python-client
```
これでYoutube APIの使用準備は完了です。

#Youtube Data APIで動画の情報を取得する
以下ではYoutube Data APIを用いて動画の情報を取得していきます。
具体的にどんな情報が取得できるかは[Youtube Data APIのリファレンス] (https://qiita.com/Hironsan/items/513b9f93752ecee9e670)をご確認ください。

##特定キーワードを含むタイトルの動画を再生回数順で取得する
最近ボードゲームにハマりつつあるので、ボードゲーム関連の動画情報を再生回数が多い順に取得したいと思います。

```python
from apiclient.discovery import build

YOUTUBE_API_KEY = '自分のAPIキーを入力'

youtube = build('youtube', 'v3', developerKey=YOUTUBE_API_KEY)

search_response = youtube.search().list(
part='snippet',
#検索したい文字列を指定
q='ボードゲーム',
#視聴回数が多い順に取得
order='viewCount',
type='video',
).execute()
```
上記スクリプトを用いてJSON形式で動画情報を取得することが可能です。
それではボードゲームの動画で最も再生回数を多い動画の情報を見てみます。

```python
search_response['items'][0]
```
```
{'kind': 'youtube#searchResult',
 'etag': '"p4VTdlkQv3HQeTEaXgvLePAydmU/0dlj0cjWp5akSv64R8VxJM--3Ok"',
 'id': {'kind': 'youtube#video', 'videoId': 'ASusE5qjoAg'},
 'snippet': {'publishedAt': '2019-05-31T11:58:15.000Z',
  'channelId': 'UCutJqz56653xV2wwSvut_hQ',
  'title': '【目指せ商品化】文理対抗！ガチンコボードゲーム作り対決！',
  'description': '東海オンエアってもう｢チャンネル登録してください｣とか｢高評価よろしくお願いします｣とか言わなくなっちゃったけど、やっぱり言ったほ...',
  'thumbnails': {'default': {'url': 'https://i.ytimg.com/vi/ASusE5qjoAg/default.jpg',
    'width': 120,
    'height': 90},
   'medium': {'url': 'https://i.ytimg.com/vi/ASusE5qjoAg/mqdefault.jpg',
    'width': 320,
    'height': 180},
   'high': {'url': 'https://i.ytimg.com/vi/ASusE5qjoAg/hqdefault.jpg',
    'width': 480,
    'height': 360}},
  'channelTitle': '東海オンエア',
  'liveBroadcastContent': 'none'}}
```
東海オンエアの動画が1位でした。やはり大人気ですね...
しかし上記のスクリプトでは一度に5件の情報しか取得できず、具体的な動画再生回数は取得できません。

##一度に多数の動画の情報を取得する
一度に多数の動画を取得し、その戻り値から必要な情報だけ抜き出してデータフレームに落とし込む関数を作成しました。それがこちらになります。

```python

#numに入れた数字×5件の情報を取得
#その他のパラメーターはAPIから情報を取得するパラメータと同じ
def get_video_info(part, q, order, type, num):
    dic_list = []
    search_response = youtube.search().list(part=part,q=q,order=order,type=type)
    output = youtube.search().list(part=part,q=q,order=order,type=type).execute()
    
    #一度に5件しか取得できないため何度も繰り返して実行
    for i in range(num):        
        dic_list = dic_list + output['items']
        search_response = youtube.search().list_next(search_response, output)
        output = search_response.execute()
    
    df = pd.DataFrame(dic_list)
    #各動画毎に一意のvideoIdを取得
    df1 = pd.DataFrame(list(df['id']))['videoId']
    #各動画毎に一意のvideoIdを取得必要な動画情報だけ取得
    df2 = pd.DataFrame(list(df['snippet']))[['channelTitle','publishedAt','channelId','title','description']]
    ddf = pd.concat([df1,df2], axis = 1)
    
    return ddf
```
上記関数を実行してみます。
今回はボードゲーム関連動画を再生回数の多い順に100件取得してみます。

```python
get_video_info(part='snippet',q='ボードゲーム',order='viewCount',type='video',num = 20)
```

このように100件の動画情報をデータフレームに落とし込むことができました。

![スクリーンショット 2019-12-16 20.00.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395230/0e669b35-259c-56d4-3091-2f42cb1058b8.png)

##動画の再生回数を取得する
続いて動画の再生回数を取得します。先ほど使用したメソッドとは別のメソッドを使用することが必要です。動画の再生回数を取得して先ほど作成したデータフレームにくっ付けます。

```python
#videoIdを入力することで、その動画の具体的な再生回数やいいね数を取得する関数を作成
def get_statistics(id):
    statistics = youtube.videos().list(part = 'statistics', id = id).execute()['items'][0]['statistics']
    return statistics

df_static = pd.DataFrame(list(df['videoId'].apply(lambda x : get_statistics(x))))

df_output = pd.concat([df,df_static], axis = 1)

df_output
```

こんな感じで動画の再生回数やいいね数、コメント数などを取得することができました。

![スクリーンショット 2019-12-16 20.06.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395230/2d7182b5-e354-1c76-36d9-30eb68e6aba2.png)

##可視化してみる
それでは簡単に可視化してみます。
再生回数上位100位以内の動画におけるチャンネル毎の累積視聴回数をグラフにしてみました。結果はこちら。

```python
df_output.groupby('channelTitle').sum().sort_values(by = 'viewCount', ascending = False).plot( kind='bar', y = 'viewCount', figsize = (25,10), fontsize = 20)
```
![スクリーンショット 2019-12-16 20.30.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395230/ed525269-cf6b-68ba-ed38-38980d22bb91.png)


やはり人気Youtuberの動画は1つ再生回数がずば抜けているので、上位は名の知れたチャンネルが連なっています。
再生回数上位100位以内の動画におけるチャンネル毎の投稿動画数をグラフにすると違う景色が見えてきます。

![スクリーンショット 2019-12-16 20.30.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395230/e6489cdb-e5da-317e-91ab-620534e03baa.png)

「ゴージャス動画」という見慣れないチャンネルが1位になりました。「ゴージャス動画」はあの芸人のゴージャスのYoutubeチャンネルのようです。精力的にボードゲームの動画をあげているようです。

#Next
このような感じで面白いデータを色々取得することができます。
Youtube Data APIを使って色々遊んで見たいなと思います。