多个帐户使用 Python 的 YouTube 数据 API

YouTube Data API with multiple accounts using Python

我正在开发一个应用程序,旨在帮助我的一个朋友更好地组织他的 YouTube 频道。他在不同的 Google 帐户上有多个频道。我正在 Python 开发这个,目前我对 YouTube 数据 API 没有太多经验,我打算使用它,因为它似乎是唯一的选择。

应用程序本身并不是很复杂。它唯一需要做的就是上传带有指定标题、描述和其他属性的视频,还应该可以对视频发表评论。我在 Google 开发者控制台中启动了一个简单的应用程序,启用了 YouTube 数据 API 并创建了一个 API 密钥和一个 OAUTH-Client ID。

到目前为止,我已经设法 post 对视频发表评论,但似乎每次我 运行 Python 脚本(目前它只是一个简单的脚本 post 是一条评论)Google 要我明确选择我想使用的帐户,并且我每次 运行 都必须授予脚本权限。

有没有办法我可以只 运行 脚本一次并告诉 Google 我想使用哪个帐户来 post 评论,提供所有权限和 Google 然后记住这一点,这样我就不必每次都明确授予权限?

另外我怎么才能切换帐户并用那个帐户上传,因为目前我总是需要选择一个,当 Google 客户端弹出时,当 运行脚本。

我听说您可以获得 Google 授权的应用程序,这对这有帮助吗?或者如果我只让我的应用程序处于测试状态而不是生产状态,是否可以?

如果您有 N 个帐户并想在每个帐户上上传视频,那么您必须 运行 成功完成 N OAuth 2 authorization/authentication 流程.

对于这些 N OAuth 流程中的每一个,在成功完成每个流程后,您必须将获得的凭据数据永久保存到计算机本地存储中的单独文件中。

这很可能被认为是您的应用程序的初始化步骤(尽管在以后的任何阶段,您都可以针对您需要应用程序注意的任何其他渠道重复此步骤)。您的代码如下所示:

# run an OAuth flow; then obtain credentials data
# relative to the channel the app's user had chosen
# during that OAuth flow
from google_auth_oauthlib.flow import InstalledAppFlow
scopes = ['https://www.googleapis.com/auth/youtube']
flow = InstalledAppFlow.from_client_secrets_file(
           client_secret_file, scopes)
cred = flow.run_console()

# build an YouTube service object such that to
# be able to retrieve the ID of the channel that
# the app's user had chosen during the OAuth flow
from googleapiclient.discovery import build
youtube = build('youtube', 'v3', credentials = cred)
response = youtube.channels().list(
    part = 'id',
    mine = True
).execute()
channel_id = response['items'][0]['id']

# save the credentials data to a JSON text file
cred_file = f"/path/to/credentials/data/dir/{channel_id}.json"
with open(cred_file, 'w', encoding = 'UTF-8') as json_file:
    json_file.write(cred.to_json())

上面,client_secret_file 是包含您从 Google Developers Console 获得的应用程序客户端机密 JSON 文件的文件的完整路径。

以后,每次您要上传视频时,都必须在应用程序中选择将该视频上传到哪个频道。从你的程序逻辑的角度来看,这意味着以下事情——假设你选择了 ID 为 channel_id 的频道:请读入与 channel_id 关联的凭证数据文件,以便将其内容传递给您的 YouTube 服务对象 youtube,其构造如下所示:

# read in the credentials data associated to
# the channel identified by its ID 'channel_id'
from google.oauth2.credentials import Credentials
cred_file = f"/path/to/credentials/data/dir/{channel_id}.json"
cred = Credentials.from_authorized_user_file(cred_file)

# the access token need be refreshed when
# the previously saved one expired already
from google.auth.transport.requests import Request
assert cred and cred.valid and cred.refresh_token
if cred.expired:
    cred.refresh(Request())
    # save credentials data upon it got refreshed
    with open(cred_file, 'w', encoding = 'UTF-8') as json_file:
        json_file.write(cred.to_json())

# construct an YouTube service object through
# which any API invocations are authorized on
# behalf of the channel with ID 'channel_id'
from googleapiclient.discovery import build
youtube = build('youtube', 'v3', credentials = cred)

根据 运行 此代码,YouTube 服务对象 youtube 将以这样的方式初始化,即通过此对象发出的每个 API 端点调用都将完成授权代表 channel_id.

标识的频道请求

重要说明:您需要安装软件包 Google Authentication Library for Pythongoogle-auth、版本 >= 1.21.3(google-auth v1.3.0 引入 Credentials.from_authorized_user_file、 v1.8.0 引入了 Credentials.to_json 并且 v1.21.3 修复了后一个函数 w.r.t. 它的 class' expiry 成员),用于保存凭证对象 cred到 JSON 个文本文件并从中加载。

还有一个重要提示:上面的代码已尽可能简化。根本不处理错误情况。例如,当写出新的凭证数据文件时 cred_file 已经存在或读取凭证数据时 cred_file 不存在时,上面的代码不会处理错误情况应该已经存在了。