你想要了解 YouTube(油管)视频详情 API 的调用方式、JSON 返回结构及解析方法,核心是掌握「API 认证、请求构造、JSON 字段解读、实战解析」四大关键点。以下是从API 基础配置→完整 JSON 结构→核心字段解析→Python 实战代码的全流程指南,适配数据采集、分析等业务场景。
一、 前置准备:YouTube Data API v3 基础配置
1. 核心前提(必做)
YouTube 视频详情依赖 YouTube Data API v3,需先完成:
登录Google Cloud 控制台,创建项目并启用「YouTube Data API v3」;
创建 API 密钥(API Key)或 OAuth 2.0 凭证(仅需公开数据时用 API Key 即可);
注意配额限制:免费版每日配额 10,000 单位(单条视频详情请求消耗 1 单位),超配额会返回
403 Quota Exceeded。
2. 核心接口:Videos.list(获取视频详情)
| 接口信息 | 说明 |
|---|---|
| 请求方式 | GET |
| 基础 URL | https://www.googleapis.com/youtube/v3/videos |
| 核心参数 | id(视频 ID)、part(返回数据模块)、key(API 密钥) |
二、 视频详情 API 请求构造(最简示例)
1. 关键请求参数
| 参数名 | 必填 | 取值示例 | 作用 |
|---|---|---|---|
id | 是 | dQw4w9WgXcQ(视频 ID) | 指定查询的视频(多个 ID 用逗号分隔) |
part | 是 | snippet,statistics,contentDetails | 指定返回的数据模块(多模块用逗号分隔) |
key | 是 | AIzaSyXXXXXXX(你的 API 密钥) | 身份认证 |
maxResults | 否 | 50 | 批量查询时返回的最大条数(默认 5) |
2. Python 最简请求代码
python
运行
import requests# 配置项(替换为你的信息)API_KEY = "你的Google API密钥"VIDEO_ID = "dQw4w9WgXcQ" # YouTube视频ID(从视频URL中提取:https://youtu.be/dQw4w9WgXcQ)def get_youtube_video_detail():
"""调用YouTube视频详情API,获取原始JSON数据"""
url = "https://www.googleapis.com/youtube/v3/videos"
params = {
"id": VIDEO_ID,
"part": "snippet,statistics,contentDetails,status", # 返回4个核心模块
"key": API_KEY }
try:
response = requests.get(url, params=params, timeout=15)
response.raise_for_status() # 抛出HTTP错误
json_data = response.json()
return json_data except Exception as e:
print(f"请求失败:{e}")
return None# 执行调用,获取原始JSONraw_json = get_youtube_video_detail()if raw_json:
# 格式化打印JSON(便于查看结构)
import json print(json.dumps(raw_json, ensure_ascii=False, indent=2))三、 YouTube 视频详情 JSON 完整结构解析
返回的 JSON 核心包含
items数组(每个元素对应一个视频),单视频数据分为snipet(基础信息)、statistics(统计数据)、contentDetails(内容详情)、status(状态)四大模块,以下是完整示例与字段说明:1. 完整 JSON 返回示例
json
{
"kind": "youtube#videoListResponse",
"etag": "XXXXXXXXXX",
"items": [
{
"kind": "youtube#video",
"etag": "XXXXXXXXXX",
"id": "dQw4w9WgXcQ",
"snippet": {
"publishedAt": "2009-10-25T07:18:22Z",
"channelId": "UCX6OQ3DkcsbYNE6H8uQQuVA",
"title": "Rick Astley - Never Gonna Give You Up (Official Music Video)",
"description": "Official Music Video for “Never Gonna Give You Up” by Rick Astley...",
"thumbnails": {
"default": {"url": "https://i.ytimg.com/vi/dQw4w9WgXcQ/default.jpg", "width": 120, "height": 90},
"medium": {"url": "https://i.ytimg.com/vi/dQw4w9WgXcQ/mqdefault.jpg", "width": 320, "height": 180},
"high": {"url": "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg", "width": 480, "height": 360}
},
"channelTitle": "Rick Astley",
"tags": ["Rick Astley", "Never Gonna Give You Up", "80s"],
"categoryId": "10", // 10=音乐类
"liveBroadcastContent": "none",
"localized": {
"title": "Rick Astley - Never Gonna Give You Up (Official Music Video)",
"description": "..."
}
},
"statistics": {
"viewCount": "1400000000", // 播放量
"likeCount": "10000000", // 点赞数
"dislikeCount": "0", // YouTube已隐藏该字段,固定为0
"favoriteCount": "0",
"commentCount": "500000" // 评论数
},
"contentDetails": {
"duration": "PT3M33S", // 时长(ISO 8601格式:3分33秒)
"dimension": "2d",
"definition": "hd", // 清晰度:hd/fhd/sd
"caption": "true", // 是否有字幕
"licensedContent": true // 是否为授权内容
},
"status": {
"uploadStatus": "processed",
"privacyStatus": "public", // 隐私状态:public/private/unlisted
"license": "youtube",
"embeddable": true, // 是否允许嵌入
"publicStatsViewable": true // 统计数据是否公开
}
}
],
"pageInfo": {
"totalResults": 1,
"resultsPerPage": 1
}}2. 核心字段分类说明
| 模块 | 字段名 | 类型 | 含义 | 业务价值 |
|---|---|---|---|---|
| 基础标识 | id | 字符串 | 视频唯一 ID | 数据关联核心标识 |
| snippet(基础信息) | title | 字符串 | 视频标题 | 标题关键词分析 |
description | 字符串 | 视频描述 | 关键词提取、内容分析 | |
publishedAt | 字符串 | 发布时间(UTC) | 发布时间趋势分析 | |
channelTitle | 字符串 | 频道名称 | 博主 / 频道分析 | |
thumbnails | 字典 | 缩略图 URL(多尺寸) | 素材采集 | |
tags | 数组 | 视频标签 | 关键词 / SEO 分析 | |
categoryId | 字符串 | 视频分类 ID | 品类趋势分析 | |
| statistics(统计数据) | viewCount | 字符串 | 播放量(需转整型) | 热度判断 |
likeCount | 字符串 | 点赞数 | 互动率分析 | |
commentCount | 字符串 | 评论数 | 互动热度分析 | |
| contentDetails(内容详情) | duration | 字符串 | 时长(ISO 8601) | 时长分布分析 |
definition | 字符串 | 清晰度 | 视频质量筛选 | |
| status(状态) | privacyStatus | 字符串 | 隐私状态 | 筛选公开视频 |
embeddable | 布尔值 | 是否允许嵌入 | 外链权限判断 |
四、 JSON 数据解析实战(含清洗与标准化)
解析时需处理「字段类型转换、时长格式解析、空值容错」等问题,以下是通用解析函数:
python
运行
import jsonimport isodate # 解析ISO 8601时长,需安装:pip install isodatedef parse_youtube_video_json(raw_json):
"""
解析YouTube视频详情JSON,返回标准化字典
:param raw_json: API返回的原始JSON数据
:return: 清洗后的视频信息字典
"""
if not raw_json or "items" not in raw_json or len(raw_json["items"]) == 0:
return None
# 提取第一个视频的核心数据(单视频查询时仅1条)
video_data = raw_json["items"][0]
snippet = video_data.get("snippet", {})
statistics = video_data.get("statistics", {})
content_details = video_data.get("contentDetails", {})
status = video_data.get("status", {})
# 解析时长(ISO 8601 → 秒数)
duration_iso = content_details.get("duration", "PT0S")
try:
duration_seconds = isodate.parse_duration(duration_iso).total_seconds()
duration_min = round(duration_seconds / 60, 1) # 转为分钟(保留1位小数)
except:
duration_min = 0.0
# 标准化解析(全容错)
parsed_result = {
"视频ID": video_data.get("id", ""),
"标题": snippet.get("title", "").strip(),
"发布时间": snippet.get("publishedAt", ""),
"频道名称": snippet.get("channelTitle", "未知"),
"视频描述": snippet.get("description", "").strip()[:500], # 截取前500字
"标签": ",".join(snippet.get("tags", [])), # 数组转字符串
"分类ID": snippet.get("categoryId", ""),
# 统计数据(字符串转整型,默认0)
"播放量": int(statistics.get("viewCount", 0)),
"点赞数": int(statistics.get("likeCount", 0)),
"评论数": int(statistics.get("commentCount", 0)),
# 内容详情
"时长(分钟)": duration_min,
"清晰度": content_details.get("definition", "sd"),
"是否有字幕": content_details.get("caption", "false") == "true",
# 状态信息
"隐私状态": status.get("privacyStatus", "unknown"),
"是否允许嵌入": status.get("embeddable", False),
# 缩略图(取最高清)
"高清缩略图URL": snippet.get("thumbnails", {}).get("high", {}).get("url", "")
}
return parsed_result# 调用示例if raw_json:
parsed_video = parse_youtube_video_json(raw_json)
print("=== 解析后的视频详情 ===")
for key, value in parsed_video.items():
print(f"{key}:{value}")五、 批量视频解析(多 ID 查询)
支持批量传入多个视频 ID(用逗号分隔),一次请求获取多条数据,减少配额消耗:
python
运行
def batch_parse_videos(video_ids):
"""
批量解析多个YouTube视频
:param video_ids: 视频ID列表,如["id1", "id2"]
:return: 标准化视频列表
"""
url = "https://www.googleapis.com/youtube/v3/videos"
params = {
"id": ",".join(video_ids), # 多ID逗号分隔
"part": "snippet,statistics,contentDetails",
"key": API_KEY,
"maxResults": 50 # 最多50条
}
try:
response = requests.get(url, params=params, timeout=15)
response.raise_for_status()
raw_json = response.json()
except Exception as e:
print(f"批量请求失败:{e}")
return []
# 批量解析
video_list = []
for video in raw_json.get("items", []):
# 构造单视频的JSON结构,复用解析函数
single_video_json = {"items": [video]}
parsed = parse_youtube_video_json(single_video_json)
if parsed:
video_list.append(parsed)
return video_list# 调用示例# VIDEO_IDS = ["dQw4w9WgXcQ", "9bZkp7q19f0"]# batch_result = batch_parse_videos(VIDEO_IDS)# for idx, video in enumerate(batch_result, 1):# print(f"\n{idx}. {video['标题']} | 播放量:{video['播放量']}")六、 常见问题与解决方案
| 问题现象 | 原因 | 处理方法 |
|---|---|---|
403 Forbidden (Quota Exceeded) | 超出每日配额(10,000 单位) | 1. 优化请求(批量查询);2. 申请提升配额;3. 多 API 密钥轮换 |
400 Bad Request | part参数缺失 / 格式错误 | 确保part参数包含至少一个模块(如snippet) |
dislikeCount固定为 0 | YouTube 已隐藏该字段 | 放弃使用该字段,改用点赞数 / 评论数分析互动 |
| 时长解析失败 | ISO 8601 格式异常 | 用isodate库解析,添加异常捕获 |
| 中文标题 / 描述乱码 | 编码问题 | 打印时添加ensure_ascii=False |
七、 配额优化策略
批量查询:一次请求传入最多 50 个视频 ID,减少请求次数(单请求消耗 1 单位,而非 50 单位);
按需指定 part:仅请求业务需要的模块(如仅
snippet,statistics),不浪费配额;缓存数据:对非实时数据(如发布时间、标题)缓存 24 小时,避免重复请求;
密钥轮换:多 API 密钥轮用,突破单密钥配额限制(合规范围内)。
总结
YouTube 视频详情 API JSON 解析的核心要点:
认证核心:API Key 是必填参数,需注意每日配额限制;
结构理解:核心数据集中在
snippet(基础)、statistics(统计)、contentDetails(内容)模块;解析关键:处理字段类型转换(播放量转整型)、时长格式解析(ISO 8601→分钟)、空值容错;
配额优化:批量查询 + 按需选字段 + 缓存,最大化利用免费配额。