[14日目] PythonでYouTubeライブのコメントデータを取得する

こんにちは、なりかくんと申します。
この記事はなりかくん Advent Calender 2023の14日目の記事です。

今日は、PythonでYouTubeライブのコメントデータを取得するコードを紹介していこうと思います。

# YouTubeのデータを取得するライブラリ
まず最初にYouTubeのデータを取得するために、`yt-dlp`というライブラリを利用します。

https://github.com/yt-dlp/yt-dlp

インストールは、pipコマンドで行う事が出来ます。

```
pip install -U yt-dlp
```

# yt-dlpの基本を触る
まず最初に`yt-dlp`の基礎から触れておきます。
このライブラリでは、YouTube上の動画のダウンロードを行う事が出来ます。
ダウンロードするコードは以下のコードです。

```python
from yt_dlp import YoutubeDL

videoUrl = "https://www.youtube.com/watch?v=psMKkDa61_E"
with YoutubeDL({'format': 'best'}) as ydl:
    ydl.download([videoUrl])
```

このコードを実行すると、動画のダウンロードをすぐに行う事が出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549951/06ff329a-af3a-4182-28b7-16de169a9fad.png)

私の環境では、3時間の動画を5分程度でダウンロード出来ました。クソ長い動画でも非常に早くでダウンロードできるのが非常に良い点ですね。

# ダウンロード先の指定
このままだとPythonの実行したフォルダーに保存されるので、ユーザーのダウンロードフォルダーに保存するようにします。
ダウンロードパスは`os`標準モジュールを利用して、以下のコードで取得できます。

```python
from os.path import expanduser
folderPath = expanduser("~") + "\\Downloads"
```

また、yt-dlpは以下のようになります。
```python
from yt_dlp import YoutubeDL
from os.path import expanduser

folderPath = expanduser("~") + "\\Downloads"
videoUrl = "https://www.youtube.com/watch?v=psMKkDa61_E"

with YoutubeDL({'format': 'best', 'outtmpl': folderPath + '/%(id)s.mp4'}) as ydl:
    ydl.download([videoUrl])
```

# YouTubeライブのコメント取得
では、次に本題のコメントデータを取得するコードです。
コメントデータを取得するには、`writesubtitles`オプションを有効化すれば取れるみたいです。原理はわからないです。
また、動画データが不要な場合は`skip_download`を有効化すれば大丈夫です。
これらを踏まえたコードがこちらになります。
```python
from yt_dlp import YoutubeDL
from os.path import expanduser

folderPath = expanduser("~") + "\\Downloads"
videoUrl = "https://www.youtube.com/watch?v=psMKkDa61_E"

with YoutubeDL({
        'format': 'best',
        'outtmpl': folderPath + '/%(id)s.mp4',
        'writesubtitles': True,
        'skip_download': True
    }) as ydl:
    ydl.download([videoUrl])
```

実行すれば、このように取得することが出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549951/a003cd49-bbd6-ceca-8c75-e59ecc7a737e.png)

ダウンロードしたコメントデータはこのようなデータです。1行ごとにデータが入っている感じですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549951/aac1b28c-c084-07de-61bb-e8de7048fcc9.png)

# コメントデータのコメントだけを取り出す
今のままだと１行ごとにJSONが入っていて扱いにくい状態です。もういっそのことコメント内容だけを取り出ししてしまえ！ということで、各行のJSONをパースして出力するコードが以下になります。

```python
from yt_dlp import YoutubeDL
from os.path import expanduser
import json

folderPath = expanduser("~") + "\\Downloads"
videoUrl = "https://www.youtube.com/watch?v=psMKkDa61_E"

with YoutubeDL({
        'format': 'best',
        'outtmpl': folderPath + '/%(id)s.mp4',
        'writesubtitles': True,
        'skip_download': True
    }) as ydl:
    res = ydl.extract_info(videoUrl, download=False)
    ydl.download([videoUrl])

file = open(folderPath + "\\" + str(res["id"]) + ".live_chat.json", "r", encoding="UTF-8")
data = file.read()
lines = str(data).split("\n")
for line in lines:
    if line == "":
        continue
    lJson = json.loads(line)
    jAction = lJson["replayChatItemAction"]["actions"][0]
    if "addChatItemAction" in jAction:
        jItem = jAction["addChatItemAction"]["item"]
        if "liveChatTextMessageRenderer" in jItem:
            commentContent = jItem["liveChatTextMessageRenderer"]["message"]["runs"][0]["text"]
            print(str(commentContent))
```

出力結果は以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549951/f40e183f-2403-f7e6-6abb-78d3fc766afe.png)

# 活用すれば
これを活用すれば、各時間にどのぐらいのコメント数があるのかなどをグラフ化することが出来ます。これから何記事かこのネタで持たそうと思います。

最後までお読みいただきありがとうございました。