You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何调用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的实际资源数据,创建或修改资源时必须传递的内容。

报错的核心原因有两点:

  1. 插入播放列表项必须包含snippet字段:调用PlaylistItems Insert接口时,body里必须有snippet字段(内含playlistId和resourceId),这是创建播放列表项的必填内容,没有它API不知道要把视频插到哪个列表里。
  2. part参数要和body提交的字段匹配:你把part设为contentDetails,但body里实际传的是snippet的数据,API会判定参数不匹配——你告诉它要返回contentDetails相关数据,但提交的却是snippet的内容,自然触发unexpectedPart错误。

如果确实需要返回contentDetails字段,可以把part设为'snippet,contentDetails'(多个字段用逗号分隔);要是还需要设置contentDetails的内容(比如视频在播放列表中的起止时间),再在body里添加对应的字段即可。

内容的提问来源于stack exchange,提问作者Bitmapper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 09:20:12