前提・実現したいこと
PythonでYoutube Liveのアーカイブからチャットを取得したいです。
こちらのサイトのコードをほぼそのまま使用しています。
https://github.com/geerlingguy/youtube_chat_crawler/blob/master/YoutubeChatReplayCrawler.py
コードは下記について変更しています。
→youtubeの動画IDを引数としてvideo_idに入れているのを、初めからtarget_urlに打ち込んでいます。したがって、引数の長さを判別する箇所もコメントアウトしています。
発生している問題・エラーメッセージ
pyファイルを実行し作成されるテキストファイル(comment_data.txt)を開いても中身が空っぽです。
cmd,Visual Studio Code共にエラーメッセージは発生していません。
指定した動画からコメントを取得する流れのどこかで想定通りに動いていないと思われますが、
解決策が分からなくて困っています。
該当のソースコード
Python
1#!/usr/bin/env python3 2from bs4 import BeautifulSoup 3import ast 4import requests 5import re 6import sys 7# Verify user supplied a YouTube URL. 8#if len(sys.argv) == 1: 9# print("Please provide a YouTube URL (e.g. ./YoutubeChatReplayCrawler.py YOUTUBE_VIDEO_URL)") 10# sys.exit(0) 11# Produce a valid filename (from Django text utils). 12def get_valid_filename(s): 13 s = str(s).strip().replace(' ', '_') 14 return re.sub(r'(?u)[^-\w.]', '', s) 15# Set up variables for requests. 16#target_url = sys.argv[1] 17target_url = "https://www.youtube.com/watch?v=mOBvvwCosE4" #←適当に選んだ動画のURL 18dict_str = '' 19next_url = '' 20comment_data = [] 21session = requests.Session() 22headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'} 23# Get the video page. 24html = session.get(target_url) 25soup = BeautifulSoup(html.text, 'html.parser') 26# Retrieve the title and sanitize so it is a valid filename. 27title = soup.find_all('title') 28title = title[0].text.replace(' - YouTube', '') 29title = get_valid_filename(title) 30# Regex match for emoji. 31RE_EMOJI = re.compile('[\U00010000-\U0010ffff]', flags=re.UNICODE) 32# Find any live_chat_replay elements, get URL for next live chat message. 33for iframe in soup.find_all("iframe"): 34 if("live_chat_replay" in iframe["src"]): 35 next_url = iframe["src"] 36if not next_url: 37 print("Couldn't find live_chat_replay iframe. Maybe try running again?") 38 sys.exit(0) 39# TODO - We should fail fast if next_url is empty, otherwise you get error: 40# Invalid URL '': No schema supplied. Perhaps you meant http://? 41# TODO - This loop is fragile. It loops endlessly when some exceptions are hit. 42while(1): 43 try: 44 html = session.get(next_url, headers=headers) 45 soup = BeautifulSoup(html.text, 'lxml') 46 # Loop through all script tags. 47 for script in soup.find_all('script'): 48 script_text = str(script) 49 if 'ytInitialData' in script_text: 50 dict_str = ''.join(script_text.split(" = ")[1:]) 51 # Capitalize booleans so JSON is valid Python dict. 52 dict_str = dict_str.replace("false", "False") 53 dict_str = dict_str.replace("true", "True") 54 # Strip extra HTML from JSON. 55 dict_str = re.sub(r'};.*\n.+</script>', '}', dict_str) 56 # Correct some characters. 57 dict_str = dict_str.rstrip(" \n;") 58 # TODO: I don't seem to have any issues with emoji in the messages. 59 # dict_str = RE_EMOJI.sub(r'', dict_str) 60 # Evaluate the cleaned up JSON into a python dict. 61 dics = ast.literal_eval(dict_str) 62 # TODO: On the last pass this returns KeyError since there are no more 63 # continuations or actions. Should probably just break in that case. 64 continue_url = dics["continuationContents"]["liveChatContinuation"]["continuations"][0]["liveChatReplayContinuationData"]["continuation"] 65 print('Found another live chat continuation:') 66 print(continue_url) 67 next_url = "https://www.youtube.com/live_chat_replay?continuation=" + continue_url 68 # Extract the data for each live chat comment. 69 for samp in dics["continuationContents"]["liveChatContinuation"]["actions"][1:]: 70 comment_data.append(str(samp) + "\n") 71 # next_urlが入手できなくなったら終わり 72 except requests.ConnectionError: 73 print("Connection Error") 74 continue 75 except requests.HTTPError: 76 print("HTTPError") 77 break 78 except requests.Timeout: 79 print("Timeout") 80 continue 81 except requests.exceptions.RequestException as e: 82 print(e) 83 break 84 except KeyError as e: 85 error = str(e) 86 if 'liveChatReplayContinuationData' in error: 87 print('Hit last live chat segment, finishing job.') 88 else: 89 print("KeyError") 90 print(e) 91 break 92 except SyntaxError as e: 93 print("SyntaxError") 94 print(e) 95 break 96 # continue #TODO 97 except KeyboardInterrupt: 98 break 99 except Exception: 100 print("Unexpected error:" + str(sys.exc_info()[0])) 101# Write the comment data to a file named after the title of the video. 102with open(title + ".json", mode='w', encoding="utf-8") as f: 103 f.writelines(comment_data) 104print('Comment data saved to ' + title + '.json')
試したこと
・実行時、すぐ"Couldn't find live_chat_replay iframe. Maybe try running again?"と表示されるので、while(1):のループに入る前を見ていけば良いと考えました。
・そこで、デバッグによって各変数の状態を確認したところ、next_url=""のままでした。よって、>>if("live_chat_replay" in iframe["src"]):は一度もTrueにならなかったと考えています。(Trueなら何かしら代入されているため)
・上記条件式で使用されるiframeの中にはいろんなタグが入っていました。"src"に関係ありそうな箇所(自信ないです)を載せておきます。
回答1件
あなたの回答
tips
プレビュー