pythonで模写してみた
Pythonならyoutubeのアーカイブのチャット欄からコメントを取得できると思い、手を付けてみた。(実際はLIVEチャットの取得のみでアーカイブからではなかった)
どこをどう持っていけばよいのか参考にした動画を見ながら、Youtube DATA API のリファレンスで試していった。
正直いきなりやるものではないと思った笑
ただ、需要があるおかげでコードはyoutubeにあったので2日かけて少しずつ理解しながらなんとか模写。
(ちなみにここにコピーしたコードのインデントはスペースを開けてもブログのブラウザに反映されてないかも…)
こちらが模写したコード。
import json
import time
import re
import datetime as dt
import matplotlib.pyplot as plt
from googleapiclient.discovery import build
class YouTubeLiveChat:
def __init__(self, _video_id):
self.video_id = _video_id
# execute is used for connecting database
_res = _youtube.videos().list(
part='liveStreamingDetails', id=_video_id).execute()
self.liveChat_id = _res['items'][0]['liveStreamingDetails']['activeLiveChatId']
_publishedAt = _res['items'][0]['liveStreamingDetails']['actualStartTime']
# youtubeライブラリをこれで使えるようになる
self.pattern = '[T0-9-:]+'
self.publishedAt = self.set_publishedAt_format(_publishedAt)
def get_liveChat(self, _next_page_token):
#get_liveChatにアクセスするためだけにこの関数があるのでとりあえずreturnで返している
liveChatId=self.liveChat_id,
part='snippet',
maxResults=2000,
pageToken=_next_page_token
).execute()
_next_page_token = None
_liveChats =
_access_count = 0
while 1:
_res = self.get_liveChat(_next_page_token)
# scope秒にコメントが0件の場合はリストを飛ばしている
if len(_res['items']) > 0:
_liveChats.append(_res['items'])
_access_count += 1
print("コメントを" + str(len(_res['items'])) + "件取得")
_next_page_token = _res['nextPageToken']
break
print(str(
self.convert_milisec_to_seconds(
_res['pollingIntervalMillis'])
) + "秒後にアクセス")
# timeのsleep関数で次のコメント取得まで待機させている
time.sleep(self.convert_milisec_to_seconds(_res['pollingIntervalMillis']))
return _liveChats
def assemble_page(self, _liveChats, _scope): # _scope=何秒のスパンでデータ取得するか
_datas =
for _items in _liveChats:
for _item in _items:
# 正規表現で時間を計算できる値にする(情報を型落ちさせる)
_dt = self.set_publishedAt_format(_item['snippet']['publishedAt'])
# 今の時間 - 開始した時間 = 動画のコメント取得している時間(秒)を割り出している
# _scope秒で合計時間(秒)を割ることで時間をまとめている
_datas.append(_dt - (_dt % _scope))
return _datas
# 同じ時間のコメントをまとめるための辞書
#オブジェクトはintではなくstrでないと使えない
# これを適用することで定義された戻り値をオブジェクトに付与できる。
def createDict(self, _datas):
_dct = {}
for _data in _datas:
_dct.setdefault(_data, 0)
_dct[_data] += 1
return _dct
def pyplot_show_liveChat(self, _liveChats, _scope):
_datas = self.assemble_page(_liveChats, _scope=_scope)
_dct = self.createDict(_datas)
_ls = []
# はdefで関数を作らなくても引数を使うことができる
_ls = sorted(_dct.items(), key=lambda x: x[0])
_x = [str(dt.timedelta(hours=e[0]/3600)) for e in _ls]
_y = [int(e[1]) for e in _ls]
plt.plot(_x, _y)
plt.show()
_d = {}
_d.update(zip(_x, _y))
def set_publishedAt_format(self, _publishedAt):
# 正規表現で必要な情報だけ取得
return dt.datetime.strptime(re.findall(self.pattern, _publishedAt)[0],
'%Y-%m-%dT%H:%M:%S')
def convert_milisec_to_seconds(self, _milisec):
return (_milisec/1000)
def __str__(self):
# モジュールを直接実行したときにだけ、実行したいコード
return f'{self.video_id}, {self.liveChat_id}, {self.publishedAt}'
if __name__ == '__main__':
_video_id = '動画のid'
ylc = YouTubeLiveChat(_video_id)
ylc.pyplot_show_liveChat(datas, _scope=60)
*1:_dt - self.publishedAt).total_seconds(