去年,我能够通过 Playlistitems > list 指定包含所有上传的播放列表来检索所有状态的视频(通过 OAuth 进行身份验证后)。
截至今天,相同的代码只能给我公开上传:
import os
import google_auth_oauthlib.flow
import googleapiclient.discovery
import googleapiclient.errors
scopes = ["https://www.googleapis.com/auth/youtube.readonly"]
def main():
# Disable OAuthlib's HTTPS verification when running locally.
# *DO NOT* leave this option enabled in production.
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
api_service_name = "youtube"
api_version = "v3"
client_secrets_file = "CLIENT_SECRETS.json"
# Get credentials and create an API client
flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(
client_secrets_file, scopes)
credentials = flow.run_console()
youtube = googleapiclient.discovery.build(
api_service_name, api_version, credentials=credentials)
request = youtube.playlistItems().list(part="snippet", maxResults=50, playlistId="__PLAYLIST__ID")
response = request.execute()
total = response['pageInfo']['totalResults']
print("total number of videos is " + str(total));
exit();
if __name__ == "__main__":
main()
我知道其他人也问过这个问题,但他们要么是非常老的帖子,要么没有得到全面的回答。
唯一的其他可能方法似乎是 Search > list 指定频道 ID,但这也只返回公共视频,尽管通过 OAuth 进行身份验证:
import os
import google_auth_oauthlib.flow
import googleapiclient.discovery
import googleapiclient.errors
scopes = ["https://www.googleapis.com/auth/youtube.force-ssl"]
def main():
# Disable OAuthlib's HTTPS verification when running locally.
# *DO NOT* leave this option enabled in production.
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
api_service_name = "youtube"
api_version = "v3"
client_secrets_file = "YOUR_CLIENT_SECRET_FILE.json"
# Get credentials and create an API client
flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(
client_secrets_file, scopes)
credentials = flow.run_console()
youtube = googleapiclient.discovery.build(
api_service_name, api_version, credentials=credentials)
request = youtube.search().list(
part="snippet",
channelId="___CHANNEL__ID___",
type="video"
)
response = request.execute()
print(response)
if __name__ == "__main__":
main()
参数的文档claims:
[...] 只能在适当的授权请求中使用。
参数将搜索限制为仅检索经过身份验证的用户拥有的视频。如果将此参数设置为forMine
,则true
参数的值也必须设置为type
。video
但是,当我将
forMine
设置为 true
时,这会导致无效请求。
任何关于如何当前获取私人/不公开的 YouTube 视频数据的建议将不胜感激。
我不会太依赖totalResults
;该属性的具体规格并不可靠(下面的重点是我的):
结果集中的结果总数。如果只需要给定播放列表的请注意,该值是一个近似值,可能不代表精确值。此外,最大值为 1,000,000。
您不应使用此值来创建分页链接。相反,请使用
nextPageToken
和prevPageToken
属性值来确定是否显示分页链接。
项目数(由其 ID PLAYLIST_ID
标识),我建议使用
Playlists.list
查询 id=PLAYLIST_ID
API 端点并查找属性
contentDetails.itemCount
.
但是,否则,如果在分页时(使用 端点),API 不会为您提供所有私有和未列出的视频(假设您向端点传递了有效的访问令牌),那么很可能这是 API 的一个错误,需要报告。
另外,请注意,根据 YouTube 工作人员的说法,通过设计为通过 PlaylistItems.list
端点返回的项目数量设定了 20000 个上限(注意:设计本身会随着时间的推移而变化:据我所知)要知道,不久前这个限制还不存在)。
youtube = googleapiclient.discovery.build('youtube', 'v3', credentials=credentials)
r = youtube.channels().list(
part='contentDetails',
mine=True).execute()
uploads_playlist_id = r['items'][0]['contentDetails']['relatedPlaylists']['uploads']
接下来,您可以获取此播放列表中的所有视频
r = youtube.playlistItems().list(playlistId=uploads_playlist_id,
part=snippet, maxResults=50).execute()
for item in r['items']:
#...