質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

YouTube

YouTubeとはユーザーがビデオをアップロード・共有・閲覧できるビデオ共有ウェブサイトです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

0回答

907閲覧

PythonでYoutube Liveのアーカイブからチャットを取得したい

退会済みユーザー

退会済みユーザー

総合スコア0

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

YouTube

YouTubeとはユーザーがビデオをアップロード・共有・閲覧できるビデオ共有ウェブサイトです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/01/29 15:38

編集2021/01/31 09:23

前提・実現したいこと

PythonでYoutube Liveのアーカイブからチャットを取得したいです。
こちらの質問のソースコードを参照しています。
https://teratail.com/questions/276731

発生している問題

pyファイルをcmdから実行し、エラーメッセージが返ってきます。
作成されるJSONファイル(タイトル名.Json)を開いても中身が空っぽです。

エラーメッセージ

SyntaxError
invalid syntax (<unknown>, line 1)
Comment data saved to タイトル名.json

該当のソースコード

python

1#!/usr/bin/env python3 2from bs4 import BeautifulSoup 3import ast 4import requests 5import re 6import sys 7import requests 8import requests_html # <= 追加 9 10# Verify user supplied a YouTube URL. 11#if len(sys.argv) == 1: 12# print("Please provide a YouTube URL (e.g. ./YoutubeChatReplayCrawler.py YOUTUBE_VIDEO_URL)") 13# sys.exit(0) 14# Produce a valid filename (from Django text utils). 15def get_valid_filename(s): 16 s = str(s).strip().replace(' ', '_') 17 return re.sub(r'(?u)[^-\w.]', '', s) 18# Set up variables for requests. 19#target_url = sys.argv[1] 20target_url = "https://www.youtube.com/watch?dummyID" #←適当に選んだ動画のURL 21dict_str = '' 22next_url = '' 23comment_data = [] 24# session = requests.Session() この行を↓に置き換え 25session = requests_html.HTMLSession() 26headers = {'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'} 27# Get the video page. 28html = session.get(target_url) 29# soup = session.get(target_url) この行を↓に置き換え 30resp = session.get(target_url) 31resp.html.render(sleep=3) # <= 追加。レンダリングを完了させるため3秒待ちます。 32# soup = BeautifulSoup(html.text, 'html.parser')  <= ここは不要なのでコメントアウトする。 33# Retrieve the title and sanitize so it is a valid filename. 34# title = soup.find_all('title') この行を↓に置き換え 35title = resp.html.find('title') 36title = title[0].text.replace(' - YouTube', '') 37title = get_valid_filename(title) 38# Regex match for emoji. 39RE_EMOJI = re.compile('[\U00010000-\U0010ffff]', flags=re.UNICODE) 40# Find any live_chat_replay elements, get URL for next live chat message. 41# for iframe in soup.find_all("iframe"): 42# if("live_chat_replay" in iframe["src"]): 43# next_url = iframe["src"] 44# この3行を↓に置き換え 45for iframe in resp.html.find("iframe"): 46 if "live_chat_replay" in iframe.attrs["src"]: 47 next_url = "".join(["https://www.youtube.com", iframe.attrs["src"]]) 48if not next_url: 49 print("Couldn't find live_chat_replay iframe. Maybe try running again?") 50 sys.exit(0) 51# TODO - We should fail fast if next_url is empty, otherwise you get error: 52# Invalid URL '': No schema supplied. Perhaps you meant http://? 53# TODO - This loop is fragile. It loops endlessly when some exceptions are hit. 54while(1): 55 try: 56 html = session.get(next_url, headers=headers) 57 soup = BeautifulSoup(html.text, 'lxml') 58 # Loop through all script tags. 59 for script in soup.find_all('script'): 60 script_text = str(script) 61 if 'ytInitialData' in script_text: 62 dict_str = ''.join(script_text.split(" = ")[1:]) 63 # Capitalize booleans so JSON is valid Python dict. 64 dict_str = dict_str.replace("false", "False") 65 dict_str = dict_str.replace("true", "True") 66 # Strip extra HTML from JSON. 67 dict_str = re.sub(r'};.*\n.+</script>', '}', dict_str) 68 # Correct some characters. 69 dict_str = dict_str.rstrip(" \n;") 70 # TODO: I don't seem to have any issues with emoji in the messages. 71 # dict_str = RE_EMOJI.sub(r'', dict_str) 72 # Evaluate the cleaned up JSON into a python dict. 73 dics = ast.literal_eval(dict_str) 74 # TODO: On the last pass this returns KeyError since there are no more 75 # continuations or actions. Should probably just break in that case. 76 continue_url = dics["continuationContents"]["liveChatContinuation"]["continuations"][0]["liveChatReplayContinuationData"]["continuation"] 77 print('Found another live chat continuation:') 78 print(continue_url) 79 next_url = "https://www.youtube.com/live_chat_replay?continuation=" + continue_url 80 # Extract the data for each live chat comment. 81# for samp in dics["continuationContents"]["liveChatContinuation"]["actions"][1:]: 82# これだと、チャットデータのブロックごとに最初の行が欠落するため、下記のようにする。 83 for samp in dics["continuationContents"]["liveChatContinuation"]["actions"]: 84 comment_data.append(str(samp) + "\n") 85 # next_urlが入手できなくなったら終わり 86 except requests.ConnectionError: 87 print("Connection Error") 88 continue 89 except requests.HTTPError: 90 print("HTTPError") 91 break 92 except requests.Timeout: 93 print("Timeout") 94 continue 95 except requests.exceptions.RequestException as e: 96 print(e) 97 break 98 except KeyError as e: 99 error = str(e) 100 if 'liveChatReplayContinuationData' in error: 101 print('Hit last live chat segment, finishing job.') 102 else: 103 print("KeyError") 104 print(e) 105 break 106 except SyntaxError as e: 107 print("SyntaxError") 108 print(e) 109 break 110 # continue #TODO 111 except KeyboardInterrupt: 112 break 113 except Exception: 114 print("Unexpected error:" + str(sys.exc_info()[0])) 115# Write the comment data to a file named after the title of the video. 116with open(title + ".json", mode='w', encoding="utf-8") as f: 117 f.writelines(comment_data) 118print('Comment data saved to ' + title + '.json') 119

試したこと

  1. 関連した質問から実施項目を検討しました。

https://teratail.com/questions/263421?link=qa_related_pc
https://teratail.com/questions/278254?link=qa_related_pc
https://teratail.com/questions/297389?link=qa_related_pc
https://teratail.com/questions/275236?link=qa_related_pc
0. bs4(BeautifulSoup)に不具合があると考え、バージョンを確認し再インストールを実施しました。
pip list
Package Version


appdirs 1.4.4
beautifulsoup4 4.9.3
bs4 0.0.1
cachetools 4.1.1
certifi 2020.6.20
chardet 4.0.0
cssselect 1.1.0
decorator 4.4.2
fake-useragent 0.1.11
ffmpeg 1.4
ffmpeg-python 0.2.0
future 0.18.2
google-api-core 1.22.1
google-api-python-client 1.10.0
google-auth 1.20.1
google-auth-httplib2 0.0.4
googleapis-common-protos 1.52.0
httplib2 0.18.1
idna 2.10
lxml 4.6.2
parse 1.16.0
pip 21.0
protobuf 3.13.0
py 1.9.0
pyasn1 0.4.8
pyasn1-modules 0.2.8
pyee 7.0.2
pyppeteer 0.2.2
pyquery 1.4.1
pytz 2020.1
requests 2.25.1
requests-html 0.10.0
retry 0.9.2
rsa 4.6
selenium 3.141.0
setuptools 41.2.0
six 1.15.0
soupsieve 2.0.1
tqdm 4.48.2
uritemplate 3.0.1
urllib3 1.26.3
w3lib 1.22.0
websockets 8.1
youtube-dl 2021.1.24.1
0. リファレンスの確認
http://kondou.com/BS4/
https://www.crummy.com/software/BeautifulSoup/

補足情報(FW/ツールのバージョンなど)

  • ver Microsoft Windows [Version 10.0.19041.746]
  • python --version Python 3.8.3

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問