为何调用YouTube API的PlaylistItems Insert时不能用contentDetails替代snippet?
YouTube API PlaylistItems Insert接口part参数报错原因解析
问题描述
我是YouTube API新手,对API请求中part与body的区别及含义十分困惑。YouTube API PlaylistItems Insert接口支持contentDetails、id、snippet、status作为参数。
以下代码可成功将视频插入播放列表:
import os import pickle from dotenv import load_dotenv from googleapiclient.discovery import build from google_auth_oauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request credentials = None # token.pickle stores the user's credentials from previously successful logins if os.path.exists('token.pickle'): print('Loading Credentials From File...') with open('token.pickle', 'rb') as token: credentials = pickle.load(token) # If there are no valid credentials available, then either refresh the token or log in. if not credentials or not credentials.valid: if credentials and credentials.expired and credentials.refresh_token: print("Refreshing Access Token...") credentials.refresh(Request()) else: print("Fetching New Tokens...") flow = InstalledAppFlow.from_client_secrets_file( 'client_secrets.json', scopes=['https://www.googleapis.com/auth/youtube'] ) flow.run_local_server(port=8080, prompt='consent', authorization_prompt_message='') credentials = flow.credentials # Save the credentials for the next run with open('token.pickle', 'wb') as f: print("Saving Credentials for Future Use...") pickle.dump(credentials, f) load_dotenv() API_KEY = os.getenv('API_KEY') with build('youtube', 'v3', credentials=credentials) as ytService: request = ytService.playlistItems().insert( part='snippet', body={ 'snippet': { 'playlistId': 'PLL_zqGJzFipIjbeZfTmJTgnoM4Gl-80Hn', 'resourceId': { 'kind': 'youtube#video', 'videoId': 'PhPqP2qUHdg' } } } ) response = request.execute() print(response)
但将part='snippet'改为part='contentDetails'时,出现如下错误:
Traceback (most recent call last): File "d:\Documents\Programming Projects\Google YouTube API\main.py", line 52, in <module> response = request.execute() File "D:\Documents\Programming Projects\Google YouTube API\.venv\lib\site-packages\googleapiclient\_helpers.py", line 130, in positional_wrapper return wrapped(*args, **kwargs) File "D:\Documents\Programming Projects\Google YouTube API\.venv\lib\site-packages\googleapiclient\http.py", line 938, in execute raise HttpError(resp, content, uri=self.uri) googleapiclient.errors.HttpError: <HttpError 400 when requesting https://youtube.googleapis.com/youtube/v3/playlistItems?part=contentDetails&alt=json returned "'snippet'". Details: "[{'message': "'snippet'", 'domain': 'youtube.part', 'reason': 'unexpectedPart', 'location': 'part', 'locationType': 'parameter'}]">
问题原因解析
先明确part和body的核心区别:
part参数:指定API响应中要返回的资源字段集合,也就是你希望接口给你返回哪些数据。body参数:是你提交给API的实际资源数据,创建或修改资源时必须传递的内容。
报错的核心原因有两点:
- 插入播放列表项必须包含
snippet字段:调用PlaylistItems Insert接口时,body里必须有snippet字段(内含playlistId和resourceId),这是创建播放列表项的必填内容,没有它API不知道要把视频插到哪个列表里。 part参数要和body提交的字段匹配:你把part设为contentDetails,但body里实际传的是snippet的数据,API会判定参数不匹配——你告诉它要返回contentDetails相关数据,但提交的却是snippet的内容,自然触发unexpectedPart错误。
如果确实需要返回contentDetails字段,可以把part设为'snippet,contentDetails'(多个字段用逗号分隔);要是还需要设置contentDetails的内容(比如视频在播放列表中的起止时间),再在body里添加对应的字段即可。
内容的提问来源于stack exchange,提问作者Bitmapper
相关产品推荐
相关产品推荐

