You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

授权后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} 未搜索到视频')

关键修复说明

  1. 将所有逻辑放入主入口块:确保授权完成后自动执行评论流程
  2. 分离关键词与视频ID存储:避免scrape函数覆盖初始关键词,视频ID写入单独文件
  3. 优化文件操作:过滤空行避免无效内容,使用正确的读写模式
  4. 简化循环逻辑:移除无意义的while循环,直接遍历关键词列表
  5. 精准捕获异常:不再吞掉所有错误,针对性处理API错误和通用错误,方便排查问题
  6. 移除无用参数:评论接口无需指定channelId,仅保留必要的videoId参数

内容的提问来源于stack exchange,提问作者user25030781

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 19:19:59