如何使用Python通过YouTube API获取任意频道订阅者列表
问题根源
你的代码同时调用了两种互斥的OAuth授权流程:run_local_server()是本地端口自动回调的无交互授权模式,run_console()是需要手动在控制台粘贴授权码的模式,重复调用这两个方法才会触发要求输入授权码的逻辑,属于代码写法错误。
另外需要提前说明:YouTube Data API v3的subscriptions.list接口本身存在隐私限制,传入channelId参数时,只能获取目标频道设置为公开可见的订阅关系,所有设置为订阅隐私的用户数据无法通过接口获取,没有绕过方法。
授权码说明
如果你使用run_console()模式,程序启动后会在控制台输出一个Google授权链接,将链接复制到浏览器打开,登录Google账号完成授权后,页面会展示一串字符串,这就是程序要求输入的授权码。普通本地开发场景不需要用这个模式,用本地回调模式更方便,全程不需要手动输入授权码。
修正后的可运行代码
提前确认你已经完成以下前置操作:
- 在Google Cloud控制台启用了YouTube Data API v3
- 创建了OAuth 2.0桌面端客户端凭证,下载的
client_secrets.json文件和脚本放在同一目录
import os import pickle from google_auth_oauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request from googleapiclient.discovery import build SCOPES = ["https://www.googleapis.com/auth/youtube.readonly"] def init_youtube_service(): creds = None # 缓存授权凭证,后续运行不需要重复走授权流程 if os.path.exists("token.pickle"): with open("token.pickle", "rb") as f: creds = pickle.load(f) # 凭证不存在或失效时重新授权 if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( "client_secrets.json", scopes=SCOPES ) # 仅保留本地服务授权模式,自动完成回调 creds = flow.run_local_server(port=8080, prompt="consent") # 保存凭证到本地 with open("token.pickle", "wb") as f: pickle.dump(creds, f) return build("youtube", "v3", credentials=creds) if __name__ == "__main__": youtube = init_youtube_service() all_subs = [] # 构造初始请求,单次最多拉取50条结果 req = youtube.subscriptions().list( part="snippet,contentDetails", channelId="UC_x5XG1OV2P6uZZ5FSM9Ttw", maxResults=50 ) # 分页拉取所有公开订阅数据 while req: resp = req.execute() all_subs.extend(resp.get("items", [])) req = youtube.subscriptions().list_next(req, resp) print(f"拉取到公开订阅者总数:{len(all_subs)}") # 打印前5条样例数据 for item in all_subs[:5]: print(f"订阅者频道:{item['snippet']['subscriberSnippet']['title']}")
运行说明
- 第一次运行脚本会自动唤起默认浏览器打开Google授权页,登录任意个人Google账号即可(不需要是目标频道的所有者,拉取公开订阅数据无账号归属要求),点击同意授权后页面会自动跳转到本地8080端口完成授权,全程不需要手动复制粘贴授权码。
- 如果你是在无图形界面的服务器上运行,删掉
run_local_server相关代码,仅保留creds = flow.run_console()即可,按照控制台提示复制链接到浏览器完成授权,再将页面给出的授权码粘贴回控制台回车即可完成认证。 - 如果需要拉取你自己账号的私有订阅列表,把请求参数里的
channelId换成mine=True即可,不需要传频道ID。
内容的提问来源于stack exchange,提问作者george bell
相关产品推荐
相关产品推荐

