Pythonで大量にあるYouTubeの動画をランダムにアクセスしてみた

初めての投稿です。

#YouTubeの仕様
YouTubeの動画のURLは以下のようなものである。
`https://www.youtube.com/watch?v=XqZsoesa55w`
ちなみにこの動画は2021年3月現在で最も再生されているYouTube動画の
[Pinkfong! Kids' Songs & Stories](https://www.youtube.com/c/pinkfong) チャンネルの
「[Baby Shark Dance | #babyshark Most Viewed Video | Animal Songs | PINKFONG Songs for Children](https://youtu.be/XqZsoesa55w)」である。[^1]

YouTubeの動画を見分けるものはURLの`/watch?v=`のあとの最後の11桁である。
`XqZsoesa55w`

この11桁は通称IDと呼ばれ、以下の文字からランダムに11桁が選ばれる。
`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_`

これは、大文字、小文字のすべてのアルファベット、数字、そして`-`と`_`を足したもので、これで64（= 2^6）個になるので都合が良いとされる。

つまり、この中からランダムに11文字選び、そのIDでできたURLでYouTubeにランダムにアクセスすればランダムに動画が見れるのではないか！？と思った。

#コード

```Python:youtube.py
from urllib import request, parse, error
import json
import random

chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'
chars_list = [char for char in chars]
id_len = 11

while True:
    video_id = ''.join(random.choices(chars_list, k = id_len))

    params = {'format': 'json', 'url': 'https://www.youtube.com/watch?v=' + video_id}
    url = 'https://www.youtube.com/oembed'
    query_string = parse.urlencode(params)
    url = url + '?' + query_string

    try:
        with request.urlopen(url) as response:
            response_text = response.read()
            data = json.loads(response_text.decode())
            print('URL: {}\nTitle: {}'.format(params['url'], data['title']))
        break
    except error.HTTPError:
        continue
```
参考サイト：
[Get title from YouTube videos - Stack Overflow](https://stackoverflow.com/questions/1216029/get-title-from-youtube-videos)
[Pythonでリストからランダムに要素を選択するchoice, sample, choices | note.nkmk.me](https://note.nkmk.me/python-random-choice-sample-choices/)

##解説
すべての文字の`str`型をつくり、そこから内包表記で`list`にする。

```Python:5-6行目
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'
chars_list = [char for char in chars]
```
***

`charsList`から11文字を重複ありで選び、できた`list`を繋げて一つの`str`にする。

```Python:10行目
    video_id = ''.join(random.choices(chars_list, k = id_len))
```

***

YouTubeのタイトルなどをJSONにして表示してくれるサイトのためURL作り。

```Python:12-15行目
    params = {'format': 'json', 'url': 'https://www.youtube.com/watch?v=' + video_id}
    url = 'https://www.youtube.com/oembed'
    query_string = parse.urlencode(params)
    url = url + '?' + query_string
```
***

動画が存在したらURLとタイトルを`print()`。存在していなかったら`urllib.error.HTTPError`を吐くので、`continue`して次の動画を探す。

```Python:17-24行目
    try:
        with request.urlopen(url) as response:
            response_text = response.read()
            data = json.loads(response_text.decode())
            print('URL: {}\nTitle: {}'.format(params['url'], data['title']))
        break
    except error.HTTPError:
        continue
```
#実用性

公式には公表されていないが、2020年現在、YouTubeには261億の動画が存在すると言われている。[^2]
先程の方法で11桁のIDを生成すると、
`64 ^ 11 = 73,786,976,294,838,206,464`
つまり7400垓ほどの動画URLを生成することができる計算になる。

先程のプログラムは私の環境下では1000個の動画URLを探すのに116.5528198秒かかった。
ここから、
`64^11 / 26100000000 * (116.5528198/1000) = 329504986.6543735305806048730728`
つまり1つの動画に当たるのに平均で3.3億秒ほどかかる計算となる。

これはつまり、
`329504986.6543735305806048730728 / 60 / 60 / 24 / 365.25 = 10.441382952264225751660610219814`
と、**10年5ヶ月**ほどとなる。

10年強ほどプログラムを回し続けることができる方は試してみてはいかがでしょうか。
ちなみに私はまだ見つけられていません。


[^1]: https://en.wikipedia.org/wiki/List_of_most-viewed_YouTube_videos
[^2]: https://www.productmanagementexercises.com/1637/estimate-the-total-number-of-videos-on-youtube