如何在Python中利用OAuth2令牌自动化调用YouTube Data API实现定时视频操作?
首先咱们先把你当前的API请求错误搞定,再一步步实现全自动化的流程。
1. 修复你的Channels API请求400错误
你写的请求参数格式完全不对,requests.get的参数应该用params传递键值对,而不是把字符串塞到data里(data是POST请求专用的)。正确的写法应该是这样:
import requests url = 'https://www.googleapis.com/youtube/v3/channels' params = { 'access_token': token_var, 'part': 'snippet', 'mine': 'true' } response = requests.get(url, params=params) # 处理响应 if response.status_code == 200: print(response.json()) else: print(f"Error: {response.status_code}, {response.text}")
这样就能正确发起请求了,之前的400错误就是因为参数传递方式和格式都错了。
2. 实现全自动化:Offline Access + 持久化Refresh Token
你提到的offline access就是实现全自动化的核心——只需要手动授权一次,拿到refresh token之后,后续就能自动用它刷新access token,完全不需要再手动干预。
步骤1:获取初始的Refresh Token(仅需手动一次)
首先,在Google Cloud Console里,确保你的OAuth客户端ID是桌面应用类型(后面会说为什么不能用Web应用),然后用以下代码获取初始的refresh token:
from google_auth_oauthlib.flow import InstalledAppFlow # 定义需要的API权限,删除/上传视频需要这些 scope SCOPES = [ 'https://www.googleapis.com/auth/youtube.upload', 'https://www.googleapis.com/auth/youtube.force-ssl' ] # 替换成你的客户端凭据文件路径(从Google Cloud Console下载的json) flow = InstalledAppFlow.from_client_secrets_file( 'client_secret_desktop.json', SCOPES ) # 设置access_type为offline,才能拿到持久化的refresh token credentials = flow.run_local_server(port=0, access_type='offline', prompt='consent') # 把凭据保存到文件,后续可以直接加载复用 import pickle with open('youtube_credentials.pickle', 'wb') as token: pickle.dump(credentials, token)
运行这段代码会弹出授权页面,手动授权一次之后,程序会把包含refresh token的凭据保存到youtube_credentials.pickle文件里,这一步只需要做一次。
步骤2:自动刷新Access Token并执行API操作
之后每次需要调用API时,直接加载保存的凭据,它会自动刷新access token(如果过期的话):
import pickle from googleapiclient.discovery import build # 加载保存的凭据 with open('youtube_credentials.pickle', 'rb') as token: credentials = pickle.load(token) # 构建YouTube Data API客户端 youtube = build('youtube', 'v3', credentials=credentials) # 示例:删除视频(需要目标视频ID) def delete_video(video_id): youtube.videos().delete(id=video_id).execute() print(f"Deleted video: {video_id}") # 示例:上传视频 def upload_video(file_path, title, description): request = youtube.videos().insert( part='snippet,status', body={ 'snippet': { 'title': title, 'description': description }, 'status': { 'privacyStatus': 'public' # 可设为private/unlisted/public } }, media_body=file_path ) response = request.execute() print(f"Uploaded video ID: {response['id']}") return response['id']
步骤3:实现定时任务
要实现每小时执行一次,推荐用schedule库(先执行pip install schedule安装):
import schedule import time def job(): print("Starting scheduled task...") # 这里写你的业务逻辑:删除旧视频、上传新视频 # 示例: # old_video_id = "你的旧视频ID" # delete_video(old_video_id) # new_video_id = upload_video("new_video.mp4", "我的新视频", "视频描述") print("Task completed.") # 每小时执行一次任务 schedule.every().hour.do(job) while True: schedule.run_pending() time.sleep(60)
3. 关于客户端类型:不需要学Django,选桌面应用凭据
你之前选Web应用类型是错误的,桌面自动化场景应该创建桌面应用类型的OAuth客户端ID:
- 登录Google Cloud Console → 你的项目 → APIs & Services → Credentials → 创建凭据 → OAuth客户端ID → 应用类型选“桌面应用”
- 下载这个客户端的json文件,就是上面代码里用的
client_secret_desktop.json
Web应用的refresh token容易失效,还需要配置回调URL,完全不适合桌面自动化场景,所以根本不需要学Django,用桌面应用凭据就够了。
4. 为什么Service Account不可行
你看到的资料是对的,YouTube Data API确实不支持Service Account——因为YouTube频道是和个人Google账号绑定的,Service Account是一个独立的虚拟账号,没有自己的YouTube频道,所以无法用来操作你的个人频道内容,这条路走不通。
内容的提问来源于stack exchange,提问作者beachboy

