使用YouTube Data v3 API playlistItems.list无法获取全部上传视频ID
解决YouTube Data API认证请求下playlistItems.list缺失公开视频的问题
问题原因
- 认证账号的内容过滤:OAuth认证所用的Google账号开启了YouTube安全模式或内容限制,导致部分公开视频被API过滤返回。
- API请求参数冲突:原代码同时传入
credentials和developerKey,API会优先使用OAuth认证,而非API Key的无限制访问权限。 - 极个别情况:频道上传列表同步延迟:频道的“上传”播放列表与实际视频库存在短暂同步差异,该情况概率极低。
解决方案
1. 关闭认证账号的内容过滤
登录认证用的Google账号,进入YouTube设置→内容限制,关闭安全模式,并清除所有视频分级过滤规则。
2. 混合请求逻辑(兼顾公开+非公开视频)
非认证请求可获取全量公开视频,认证请求可获取非公开视频,分别发起两种请求后合并去重即可得到完整列表:
修正后的代码
import os from google.oauth2.credentials import Credentials import googleapiclient.discovery import googleapiclient.errors scopes = ["https://www.googleapis.com/auth/youtube.readonly"] api_key = "MY_API_KEY" # 替换为你的API Key channel_playlist_id = "MY_CHANNEL_PLAYLIST_ID" # 替换为频道的上传播放列表ID client_secrets_file = "PATH_TO_MY_CLIENT_SECRETS_JSON" # 替换为授权文件路径 def get_authenticated_video_ids(): # 认证请求:获取非公开+部分公开视频 os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1" credentials = Credentials.from_authorized_user_file(client_secrets_file) youtube = googleapiclient.discovery.build( "youtube", "v3", credentials=credentials ) items = [] request = youtube.playlistItems().list(part='contentDetails', playlistId=channel_playlist_id) while True: response = request.execute() items.extend(response['items']) if 'nextPageToken' in response: request = youtube.playlistItems().list( part='contentDetails', playlistId=channel_playlist_id, pageToken=response['nextPageToken'] ) else: break return {i['contentDetails']['videoId'] for i in items} def get_public_video_ids(): # 非认证请求:获取全量公开视频 youtube = googleapiclient.discovery.build( "youtube", "v3", developerKey=api_key ) items = [] request = youtube.playlistItems().list(part='contentDetails', playlistId=channel_playlist_id) while True: response = request.execute() items.extend(response['items']) if 'nextPageToken' in response: request = youtube.playlistItems().list( part='contentDetails', playlistId=channel_playlist_id, pageToken=response['nextPageToken'] ) else: break return {i['contentDetails']['videoId'] for i in items} def main(): authenticated_ids = get_authenticated_video_ids() public_ids = get_public_video_ids() # 合并去重,得到完整视频ID列表 all_video_ids = list(authenticated_ids.union(public_ids)) return all_video_ids if __name__ == '__main__': video_ids = main() print(f"获取到{len(video_ids)}个视频ID")
3. 额外验证步骤
- 用
videos.list方法批量查询合并后的视频ID,确认所有视频的状态(公开/非公开)符合预期。 - 确认上传播放列表ID正确性:通过
channels.list方法(part='contentDetails')获取频道的relatedPlaylists.uploads字段,替换原代码中的播放列表ID。
内容的提问来源于stack exchange,提问作者James Laidler
相关产品推荐
相关产品推荐

