授权后YouTube评论Bot停止运行问题求助
问题描述
我正在开发一款用于提升大众对转换疗法危害认知的YouTube评论Bot,按照教程实现后,程序完成邮箱登录授权便停止运行,无法执行视频评论操作。我已添加打印语句排查,发现代码执行到指定阶段后无后续动作,推测问题出在对应代码段,现将完整代码附上,请求帮忙定位并修复该Bug。
用户提供的完整原代码:
import os import google.oauth2.credentials import requests from bs4 import BeautifulSoup import random import google_auth_oauthlib.flow from googleapiclient.discovery import build from googleapiclient.errors import HttpError from google_auth_oauthlib.flow import InstalledAppFlow CLIENT_SECRETS_FILE = "\\Users\\carte\\OneDrive\\Desktop\\YouTube-Bot-master1\\client_secret.json" SCOPES = ['https://www.googleapis.com/auth/youtube.force-ssl'] API_SERVICE_NAME = 'youtube' API_VERSION = 'v3' def get_authenticated_service(): flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES) credentials = flow.run_local_server(port=0) return build(API_SERVICE_NAME, API_VERSION, credentials = credentials) def print_response(response): print ('0') print(response) def build_resource(properties): resource = {} for p in properties: prop_array = p.split('.') ref = resource for pa in range(0, len(prop_array)): is_array = False key = prop_array[pa] if key[-2:] == '[]': key = key[0:len(key)-2:] is_array = True if pa == (len(prop_array) - 1): if properties[p]: if is_array: ref[key] = properties[p].split(',') else: ref[key] = properties[p] elif key not in ref: ref[key] = {} ref = ref[key] else: ref = ref[key] return resource def remove_empty_kwargs(**kwargs): good_kwargs = {} if kwargs is not None: for key, value in kwargs.items(): if value: good_kwargs[key] = value return good_kwargs def comment_threads_insert(client, properties, **kwargs): resource = build_resource(properties) kwargs = remove_empty_kwargs(**kwargs) response = client.commentThreads().insert( body=resource, **kwargs ).execute() return print_response(response) def scrape(keyword): url = 'https://www.youtube.com/results?q={}&sp=CAISAggBUBQ%253D'.format(keyword) source_code = requests.get(url) plain_text = source_code.text soup = BeautifulSoup(plain_text, 'html.parser') f = open('/Users/carte/OneDrive/Desktop/YouTube-Bot-master1/data/keywords.txt', 'w') for link in soup.findAll('a', {'class': 'yt-uix-tile-link'}): href = link.get('href') newhref = href.replace("/watch?v=", "") f.write(newhref + '\n') if __name__ == '__main__': os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' client = get_authenticated_service() with open(r'/Users/carte/OneDrive/Desktop/YouTube-Bot-master1/data/comments.txt') as f: foo = [line.strip() for line in f] print ('poopoo') # keyword with open(r'/Users/carte/OneDrive/Desktop/YouTube-Bot-master1/data/keywords.txt') as f: foooo = [line.strip() for line in f] print ('peepee') keywords = open(r'/Users/carte/OneDrive/Desktop/YouTube-Bot-master1/data/keywords.txt') x = 10 while x < 20: for line in keywords: scrape(line) print ('butt') with open(r'/Users/carte/OneDrive/Desktop/YouTube-Bot-master1/data/keywords.txt') as f: print ('puke') f.readline() data = f.read() f.seek(0) f.write(data) f.truncate() print ('poo') try: with open(r'/Users/carte/OneDrive/Desktop/YouTube-Bot-master1/data/keywords.txt') as f: urls = [] for url in f: rand = random.choice(foo) print ('puke') comment_threads_insert(client, {'snippet.channelId': 'UCNlM-pgjmd0NNE5I6MzlEGg', 'snippet.videoId': url, 'snippet.topLevelComment.snippet.textOriginal': rand}, part='snippet') print ('fart') except: pass print("Searching for video based in your keywords...")
问题定位与修复方案
核心问题1:主程序未执行评论逻辑
原代码中,授权完成后的所有评论逻辑代码块(读取评论、关键词、循环执行部分)都没有被包含在if __name__ == '__main__':入口块内,导致程序完成授权后直接结束,不会执行后续操作。
核心问题2:scrape函数覆盖关键词文件
scrape函数用open(..., 'w')模式打开关键词文件,会直接清空原有关键词内容,导致后续循环无法读取初始关键词。
核心问题3:文件操作逻辑错误
- 在只读模式下尝试写入文件(默认
with open是只读),操作会报错但被try-except全部吞掉,无法排查问题 - 读取并"删除"首行的逻辑完全无效,且毫无必要
核心问题4:循环逻辑冗余且错误
while x < 20循环中x值从未改变,会导致无限循环- 文件对象遍历一次后指针会移到末尾,后续无法再读取内容
修复后的完整代码
import os import google.oauth2.credentials import requests from bs4 import BeautifulSoup import random import google_auth_oauthlib.flow from googleapiclient.discovery import build from googleapiclient.errors import HttpError from google_auth_oauthlib.flow import InstalledAppFlow CLIENT_SECRETS_FILE = "/Users/carte/OneDrive/Desktop/YouTube-Bot-master1/client_secret.json" SCOPES = ['https://www.googleapis.com/auth/youtube.force-ssl'] API_SERVICE_NAME = 'youtube' API_VERSION = 'v3' def get_authenticated_service(): flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES) credentials = flow.run_local_server(port=0) return build(API_SERVICE_NAME, API_VERSION, credentials=credentials) def print_response(response): print('0') print(response) def build_resource(properties): resource = {} for p in properties: prop_array = p.split('.') ref = resource for pa in range(0, len(prop_array)): is_array = False key = prop_array[pa] if key[-2:] == '[]': key = key[0:len(key)-2:] is_array = True if pa == (len(prop_array) - 1): if properties[p]: if is_array: ref[key] = properties[p].split(',') else: ref[key] = properties[p] elif key not in ref: ref[key] = {} ref = ref[key] else: ref = ref[key] return resource def remove_empty_kwargs(**kwargs): good_kwargs = {} if kwargs is not None: for key, value in kwargs.items(): if value: good_kwargs[key] = value return good_kwargs def comment_threads_insert(client, properties, **kwargs): resource = build_resource(properties) kwargs = remove_empty_kwargs(**kwargs) response = client.commentThreads().insert( body=resource, **kwargs ).execute() return print_response(response) def scrape(keyword): url = 'https://www.youtube.com/results?q={}&sp=CAISAggBUBQ%253D'.format(keyword) source_code = requests.get(url) plain_text = source_code.text soup = BeautifulSoup(plain_text, 'html.parser') # 单独用文件存储搜索到的视频ID,避免覆盖关键词 with open('/Users/carte/OneDrive/Desktop/YouTube-Bot-master1/data/video_ids.txt', 'w') as f: for link in soup.findAll('a', {'class': 'yt-uix-tile-link'}): href = link.get('href') if '/watch?v=' in href: newhref = href.replace("/watch?v=", "") f.write(newhref + '\n') if __name__ == '__main__': os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' client = get_authenticated_service() # 读取评论内容并过滤空行 with open(r'/Users/carte/OneDrive/Desktop/YouTube-Bot-master1/data/comments.txt') as f: comments = [line.strip() for line in f if line.strip()] print('已加载评论内容') # 读取关键词并过滤空行 with open(r'/Users/carte/OneDrive/Desktop/YouTube-Bot-master1/data/keywords.txt') as f: keywords = [line.strip() for line in f if line.strip()] print('已加载关键词') # 遍历每个关键词处理 for keyword in keywords: print(f'正在处理关键词: {keyword}') scrape(keyword) # 读取搜索到的视频ID try: with open('/Users/carte/OneDrive/Desktop/YouTube-Bot-master1/data/video_ids.txt') as f: video_ids = [line.strip() for line in f if line.strip()] for vid in video_ids: try: selected_comment = random.choice(comments) print(f'正在给视频 {vid} 评论: {selected_comment}') comment_threads_insert( client, { 'snippet.videoId': vid, 'snippet.topLevelComment.snippet.textOriginal': selected_comment }, part='snippet' ) print('评论成功') except HttpError as e: print(f'评论视频 {vid} 失败: {e}') except Exception as e: print(f'未知错误: {e}') except FileNotFoundError: print(f'关键词 {keyword} 未搜索到视频')
关键修复说明
- 将所有逻辑放入主入口块:确保授权完成后自动执行评论流程
- 分离关键词与视频ID存储:避免
scrape函数覆盖初始关键词,视频ID写入单独文件 - 优化文件操作:过滤空行避免无效内容,使用正确的读写模式
- 简化循环逻辑:移除无意义的
while循环,直接遍历关键词列表 - 精准捕获异常:不再吞掉所有错误,针对性处理API错误和通用错误,方便排查问题
- 移除无用参数:评论接口无需指定
channelId,仅保留必要的videoId参数
内容的提问来源于stack exchange,提问作者user25030781
相关产品推荐
相关产品推荐

