概要
推しぶいっちゅっばが痛風で引退する前にライブ配信のアーカイブのチャット欄を保存しておきたいと思ったのでPythonでスクレイピングしました。
windows環境で行ったせいかちょっとエラーが出たのでうまくいったコードをメモします。
環境
Windows8.1
Python3.8
参考サイト
推しVのYoutubeアーカイブの各種情報を保存するためにどうすればいいのかを考えた - Qiita
推しVがいなくなった。理由もわからずに。Vtuberを推していると、いつかはVがいなくなるという事態に直面することになるだろう。引退、卒業、契約解除―呼び方は色々とあるだろうが、実態としてはVの死…
requests-HTML v0.3.4 documentation
PythonでYouTube Liveのアーカイブからチャット(コメント)を取得する(改訂版) - 雑記帳(@watagasi_)
※この記事の内容はかなり古くなっており、2020年11月頃のYouTube Liveのチャットの仕様が変わって今(2021/12/19現在)はpytchatというライブラリを使うのが良いと思われます。 github.com watagass...
やったこと
参考サイトを参考にライブ配信を取得しようとおもいます。
入れたライブラリは下記の通り、pycharmを使っていれたのでライブラリ名だけ書いておきます。
普通は pip install ライブラリ名 とかでインストールすると思います。
requests lxml requests-html google-api-python-client
このコードでは27分の動画のチャットコメントを取得していますが、コメント数6000ぐらいで、6分30秒かかっています。
sleepの時間減らしたり削除したりすればもう少し早くなると思います。
環境が悪いのかbeautifulsoup4だけだとレンダリングが遅くてチャットのURLを取得できなかったので、ブラウザ上でレンダリングするrequests-htmlを入れてそちらでhtmlを取得しました。
sleep=1は私の環境では入れないとチャットのURLが取得できなかったのでいれてあります。なのでちょっと取得に時間がかかります。
あとwindowsでtxtデータをopenにする時はエンコードを指定しないとエラーになるそうなので指定しています。
ほかはほとんど同じはず…。
書いたコードは以下の通り。
import os, os.path # from datetime import datetime from requests_html import HTMLSession LIVECOMMENTPATH = "livecomment_data" def GetLiveComment(target_id, folder=LIVECOMMENTPATH): target_url = "https://www.youtube.com/watch?v=" + target_id # セッション開始 session = HTMLSession() r = session.get(target_url) # ブラウザエンジンでHTMLを生成させる、レンダリングが遅いのかURLが取れなかったのでsleepが入っている r.html.render(sleep=1) iframe_rows = r.html.find("#chatframe") comment_data = [] for iframe in iframe_rows: if iframe.attrs["src"].find("live_chat_replay") != -1: # チャットコメントのリプレイURLを取得 next_url = "https://www.youtube.com" + iframe.attrs["src"] # print(next_url) break while True: try: html_data = session.get(next_url) html_data.html.render() for scrp in html_data.html.find("script"): if "window[\"ytInitialData\"]" in scrp.text: dict_str = scrp.text.split(" = ")[1] break dict_str = dict_str.replace("false", "False") dict_str = dict_str.replace("true", "True") dict_str = dict_str.rstrip("; \n") dics = eval(dict_str) for comment in dics["continuationContents"]["liveChatContinuation"]["actions"][1:]: comment_data.append(str(comment) + "\n") # 次のURLを検索 continuation = dics["continuationContents"]["liveChatContinuation"]["continuations"][0][ "liveChatReplayContinuationData"]["continuation"] temp = "https://www.youtube.com/live_chat_replay?continuation=" + continuation # print(temp) # print(next_url) if temp == next_url: # 時々何回取得してもnext_urlが更新されなくなるときがある。そうなると打ち切り。 break next_url = temp # next_urlがなくなる等で例外になるのでそこでbreak except: break os.makedirs(folder, exist_ok=True) path = os.path.join(folder, target_id + "_livecomment.txt") with open(path, "w", encoding="utf-8") as fp: fp.writelines(comment_data) if __name__ == "__main__": # print("start " + str(datetime.now())) VIDEOID = "yDn9UwxxDF8" # 動画ID GetLiveComment(VIDEOID) # print("done " + str(datetime.now()))
おわり。