【Python】YouTube APIを使った「再生順、更新順（再生数下限あり）」動画リスト取得（コピペでOK）

# はじめに
YouTube Data APIを使って色々とお遊び開発をしようと思っています。
とりあえず今回はAPIを使う初級編として「再生順・更新順」の動画リストを取得します。
新人プログラマ応援期間ということで、コピペで使えるようにコードをそのまま載せようと思います。

https://qiita.com/shinkai_/items/10a400c25de270cb02e4

※YouTube Data API の使用にはAPIキーが必要です。
上記の記事で取得の説明をしています。

# 準備
少しだけ準備が必要です。
必要なPythonモジュールをインストールします。

```
pip install google-api-python-client
pip install apiclient
```

# キーワードで検索（デフォルト）

まずは簡単に余計な条件を入れずにキーワードで検索してみます。

以下の条件で情報を取得

+ キーワード「YOASOBI」
+ 取得対象は「タイトル」、「動画URL」
+ 取得件数は10件

## コード
```python
from apiclient.discovery import build

API_KEY = "<APIキーを入力>"
KEY_WORD = "YOASOBI"
MAX_RESULT = 10

def youtube_search():
    youtube = build("youtube", "v3", developerKey=API_KEY)

    search_response = youtube.search().list(
      q=KEY_WORD,
      part="id,snippet",
      maxResults=MAX_RESULT
    ).execute()

    videos = []
    for search_result in search_response.get("items", []):
        if search_result["id"]["kind"] == "youtube#video":
          videos.append("%s (https://www.youtube.com/watch?v=%s)" % (search_result["snippet"]["title"],
                                     search_result["id"]["videoId"]))

    print("\n".join(videos))

if __name__ == "__main__":
    youtube_search()
```

## 出力
`タイトル（URL）`を出力しています。

```
YOASOBI「夜に駆ける」 Official Music Video (https://www.youtube.com/watch?v=x8VYWazR5mE)
YOASOBI「三原色」ahamo Special Movie (https://www.youtube.com/watch?v=ZNFKZI7L9xE)
YOASOBI - 群青  / THE FIRST TAKE (https://www.youtube.com/watch?v=NyUTYwZe_l4)
YOASOBI - 優しい彗星  / THE FIRST TAKE (https://www.youtube.com/watch?v=EaA6NlH80wg)
YOASOBI「怪物」Official Music Video　(YOASOBI - Monster) (https://www.youtube.com/watch?v=dy90tA3TT1c)
YOASOBIのベストソング - YOASOBIメドレー - YOASOBIのベストカバー  - Best Songs Of YOASOBI,夜に駆ける ,ハルジオン,あの夢をなぞって,ハッピーエンダ (https://www.youtube.com/watch?v=NXsAQtcfOyY)
YOASOBI - 夜に駆ける / THE HOME TAKE (https://www.youtube.com/watch?v=j1hft9Wjq9U)
YOASOBI「優しい彗星」Official Music Video　(YOASOBI - Comet) (https://www.youtube.com/watch?v=VyvhvlYvRnc)
夜に駆ける ／ YOASOBI (cover) by Kradness (https://www.youtube.com/watch?v=UuboPsQ7gfA)
YOASOBI「アンコール」Official Music Video (https://www.youtube.com/watch?v=vcGbefQBvJ4)
```
取得出来ました。簡単ですね。

## コードの解説（一部）
少しコードの解説もしようと思います。
まず関数「**youtube_search()**」内の下記行でyoutubeに問い合わせる準備をしています。
（APIクライアントの作成）

```python
youtube = build("youtube", "v3", developerKey=API_KEY)
```

次に下記のコードにて、YouTube APIのsearch APIのlist()関数を使って動画情報を取得しています。

```python
    search_response = youtube.search().list(
      q=KEY_WORD,
      part="id,snippet",
      maxResults=MAX_RESULT
    ).execute()
```

最後に以下のコードにて取得結果から必要な情報を抽出しています。

```python
    for search_result in search_response.get("items", []):
        if search_result["id"]["kind"] == "youtube#video":
          videos.append("%s (https://www.youtube.com/watch?v=%s)" % (search_result["snippet"]["title"],
                                     search_result["id"]["videoId"]))
```

APIの取得結果（JSON）は以下の形式です。

```json
{
  "kind": "youtube#searchResult",
  "etag": etag,
  "id": {
    "kind": string,
    "videoId": string,
    "channelId": string,
    "playlistId": string
  },
  "snippet": {
    "publishedAt": datetime,
    "channelId": string,
    "title": string,
    "description": string,
    "thumbnails": {
      (key): {
        "url": string,
        "width": unsigned integer,
        "height": unsigned integer
      }
    },
    "channelTitle": string
  }
}
```


# キーワードで検索（再生順）

次に再生順で取得したいと思います。

以下の条件で情報を取得

+ キーワード「YOASOBI」
+ 取得対象は「再生数」、「タイトル」、「動画URL」
+ 取得件数は10件
+ 再生順で出力

## コード

再生順にするにはクエリのオプション`order="viewCount"`を指定するだけです。
せっかくなので再生回数も出力したいと思います。
再生回数はAPIの別メソッド「Videos:list」を使用しないと取得出来ないため、少しだけコードが長くなります。

```python
from apiclient.discovery import build

API_KEY = "<APIキーを入力>"
KEY_WORD = "YOASOBI"
MAX_RESULT = 10
ORDER = "viewCount"

youtube = build("youtube", "v3", developerKey=API_KEY)

def get_view_count(id):
    view_count = youtube.videos().list(part = 'statistics', id = id).execute()['items'][0]['statistics']['viewCount']
    return view_count

def youtube_search():
    search_response = youtube.search().list(
      q=KEY_WORD,
      part="id,snippet",
      maxResults=MAX_RESULT,
      order=ORDER
    ).execute()

    videos = []
    for search_result in search_response.get("items", []):
        if search_result["id"]["kind"] == "youtube#video":
            view_count = get_view_count(search_result["id"]["videoId"])
            videos.append("[%s]%s (https://www.youtube.com/watch?v=%s)" % (view_count.rjust(10), search_result["snippet"]["title"],
                                     search_result["id"]["videoId"]))

    print("\n".join(videos))

if __name__ == "__main__":
    youtube_search()
```

## 出力
`[再生数]タイトル（URL）`を出力しています。 ※再生数は左空白埋め

```
[ 201551492]YOASOBI「夜に駆ける」 Official Music Video (https://www.youtube.com/watch?v=x8VYWazR5mE)
[  97120569]YOASOBI - 夜に駆ける / THE HOME TAKE (https://www.youtube.com/watch?v=j1hft9Wjq9U)
[  56332898]YOASOBI「怪物」Official Music Video　(YOASOBI - Monster) (https://www.youtube.com/watch?v=dy90tA3TT1c)
[  46933545]YOASOBI「ハルジオン」Official Music Video (https://www.youtube.com/watch?v=kzdJkT4kp-A)
[  29086025]YOASOBI「群青」Official Music Video (https://www.youtube.com/watch?v=Y4nEEZwckuU)
[  27845585]YOASOBI「たぶん」Official Music  Video (https://www.youtube.com/watch?v=8iuLXODzL04)
[  26438752]YOASOBI「あの夢をなぞって」 Official Music Video (https://www.youtube.com/watch?v=sAuEeM_6zpk)
[  23614258]YOASOBI - 群青  / THE FIRST TAKE (https://www.youtube.com/watch?v=NyUTYwZe_l4)
[  20267654]YOASOBI「アンコール」Official Music Video (https://www.youtube.com/watch?v=vcGbefQBvJ4)
[  16635646]怪物 (https://www.youtube.com/watch?v=hYF438PiuPI)
```

## 表示順指定
ここで表示順の指定が出てきたので他の表示順指定も載せておきます。

+ date – リソースを作成日の新しい順に並べます。
+ rating – リソースを評価の高い順に並べます。
+ relevance – リソースを検索クエリの関連性が高い順に並べます。このパラメータのデフォルト値です。
+ title – リソースをタイトルのアルファベット順に並べます。
+ videoCount – アップロード動画の番号順（降順）にチャンネルを並べます。
+ viewCount – リソースを再生回数の多い順に並べます。

[YouTube Data API公式ドキュメント](https://developers.google.com/youtube/v3/docs/search/list?hl=ja)

# キーワードで検索（更新順）

次に更新順（最新のもの順）で取得したいと思います。

以下の条件で情報を取得

+ キーワード「YOASOBI」
+ 取得対象は「作成日時」、「再生数」、「タイトル」、「動画URL」
+ 取得件数は10件
+ 更新順（降順）で出力

## コード

```python
from apiclient.discovery import build

API_KEY = "<APIキーを入力>"
KEY_WORD = "YOASOBI"
MAX_RESULT = 10
ORDER = "date"

youtube = build("youtube", "v3", developerKey=API_KEY)

def get_view_count(id):
    view_count = youtube.videos().list(part = 'statistics', id = id).execute()['items'][0]['statistics']['viewCount']
    return view_count

def youtube_search():
    search_response = youtube.search().list(
      q=KEY_WORD,
      part="id,snippet",
      maxResults=MAX_RESULT,
      order=ORDER
    ).execute()

    videos = []
    for search_result in search_response.get("items", []):
        if search_result["id"]["kind"] == "youtube#video":
            view_count = get_view_count(search_result["id"]["videoId"])
            videos.append("[%s][%s]%s (https://www.youtube.com/watch?v=%s)" % (search_result["snippet"]["publishedAt"], 
                                    view_count.rjust(6), search_result["snippet"]["title"], search_result["id"]["videoId"]))

    print("\n".join(videos))

if __name__ == "__main__":
    youtube_search()
```

## 出力
`[作成日時][再生数]タイトル（URL）`を出力しています。 ※再生数は左空白埋め

```
[2021-04-12T14:52:02Z][     1]群青(YOASOBI) covered by MOMOKA 2021.4.7 at CIB (https://www.youtube.com/watch?v=7HsmvKr74UI)
[2021-04-12T14:30:21Z][    19]【ハルジオン/YOASOBI】グレード５級 エレクトーン 弾いてみた (https://www.youtube.com/watch?v=wE_yQb60r08)
[2021-04-12T14:25:27Z][     4][THAISUB] YOASOBI - Tabun (たぶん) (https://www.youtube.com/watch?v=cK9w64QPKK0)
[2021-04-12T14:11:47Z][     4]YOASOBI/あの夢をなぞって　弾き語り　16歳 (https://www.youtube.com/watch?v=JvFZsT9olFI)
[2021-04-12T14:10:37Z][     2]夜に駆ける(YOASOBI) covered by MOMOKA 2021.4.7 at CIB (https://www.youtube.com/watch?v=7WVpfXbbt-I)
[2021-04-12T14:00:11Z][    89]Yasashii Suisei / 優しい彗星 by YOASOBI | BEASTARS Season 2 ED | Kalimba Tutorial &amp; Tab (Hard) (https://www.youtube.com/watch?v=cApb2qTcBEo)
[2021-04-12T14:00:14Z][    13]【作業用BGM】ヨルシカ×YOASOBI×ずとまよ代表曲メドレー【オルゴール】 (https://www.youtube.com/watch?v=rtqZsLNVTz
8)
[2021-04-12T13:45:27Z][    24]【YOASOBI 群青】アジアランカーによる最強キル集【フォートナイト/Fortnite】 (https://www.youtube.com/watch?v=1iKZPZN4prs)
[2021-04-12T13:00:13Z][   812]#341 The First Take 史上最多人同時錄音YOASOBI【群青】 ◆嘎老師 Miss Ga｜歌唱教學 學唱歌◆ (https://www.youtube.c
om/watch?v=ZVYyBugDa6o)
[2021-04-12T13:00:17Z][   118]【豊洲lovepiano5号機】通行人が立ち止まる！？YOASOBI『群青』を超絶技巧アレンジで弾いてみた！！！-YOASOBI“Gunjou
” by mina (https://www.youtube.com/watch?v=pKaXWJ_MjNk)
```
作成日時は ISO 8601（YYYY-MM-DDThh: mm:ss.sZ）形式です。今回は問題ないので変換しません。

# キーワードで検索（更新順・再生数下限設定）

更新順で取得したのは良いのですが、あんまりおもしろそうではない動画が出てきます。
（一生懸命動画作成していらっしゃる方に本当に申し訳ないですが）

そこで再生数の下限を設定したいと思います。
しかしYouTube Data APIの公式ドキュメントを見ると再生数での絞り込みが出来ないとのこと。
なので取得上限まで情報を取得して、Pythonコードで絞り込むことにしました。

以下の条件で情報を取得

+ キーワード「YOASOBI」
+ 取得対象は「作成日時」、「再生数」、「タイトル」、「URL」
+ 取得件数はMAX（上限は50件）
+ 更新順（降順）で出力
+ 再生数1,000回以上が対象

## コード
```python
from apiclient.discovery import build

API_KEY = "<APIキーを入力>"
KEY_WORD = "YOASOBI"
MAX_RESULT = 50
UNDER_VIEW_COUNT = 1000
ORDER = "date"

youtube = build("youtube", "v3", developerKey=API_KEY)

def get_view_count(id):
    view_count = youtube.videos().list(part = 'statistics', id = id).execute()['items'][0]['statistics']['viewCount']
    return view_count

def youtube_search():
    search_response = youtube.search().list(
      q=KEY_WORD,
      part="id,snippet",
      maxResults=MAX_RESULT,
      order=ORDER
    ).execute()

    videos = []
    for search_result in search_response.get("items", []):
        if search_result["id"]["kind"] == "youtube#video":
            view_count = get_view_count(search_result["id"]["videoId"])
            if int(view_count) >= UNDER_VIEW_COUNT :
                videos.append("[%s][%s]%s (https://www.youtube.com/watch?v=%s)" % (search_result["snippet"]["publishedAt"], 
                                    view_count.rjust(6), search_result["snippet"]["title"], search_result["id"]["videoId"]))

    print("\n".join(videos))

if __name__ == "__main__":
    youtube_search()
```

## 出力
`[作成日時][再生数]タイトル（URL）`を出力しています。 ※再生数は左空白埋め

```
[2021-04-12T11:00:30Z][  2121]【意外】YOASOBIの二人の最近の悩み (https://www.youtube.com/watch?v=d76QETcfBqY)
[2021-04-12T09:00:21Z][  1100]岡山駅前YOASOBIエリア【夜街探訪】岡山駅の玄関口&amp;外国人に聞いてみる (https://www.youtube.com/watch?v=UQePX0C5tXg)
[2021-04-12T09:00:00Z][ 14312]【やばすぎwwww】下ネタを真面目に話すYOASOBIの二人wwww (https://www.youtube.com/watch?v=2BwxFMzjKBs)
[2021-04-12T08:30:05Z][  1566]JPOP ランキング 邦楽 2021 ♫ Youtube Charts #01 ♫ LiSA, Hikaru Utada, Yuuri, YOASOBI, Official髭男dism, Aimyon (https://www.youtube.com/watch?v=wAUgNQLRvYk)
[2021-04-11T13:49:33Z][  3779]빨강, 파랑, 초록의 이야기🎨: YOASOBI - 삼원색(三原色) [가사/발음/한글 자막] (https://www.youtube.com/watch?v=xWN0wCmXfto)
[2021-04-11T11:00:01Z][811486]【踊ってみた】三原色 / YOASOBI (オリジナル振付) (https://www.youtube.com/watch?v=QBK9rSYGRCE)
```
良い感じになりました。
他にもオプションを変えて色々いじってみようと思っています。

まずは以下のライブラリと組み合わせて自動ダウンロードバッチを作成予定です。

https://qiita.com/shinkai_/items/7175215d7433b4cf150c

以上です。

# 公式ドキュメント
https://developers.google.com/youtube/v3/docs/search?hl=ja

https://developers.google.com/youtube/v3/code_samples/python?hl=ja