如何使用YouTube API v3按类别过滤排除视频?
解决YouTube API搜索排除特定类别的问题
我完全理解你的困扰——YouTube Data API的Search.list接口确实不支持直接通过负号或参数排除特定类别,你尝试的videoCategoryId: "-10"写法是无效的,API本身没有提供反向过滤的参数。而且直接搜索返回的snippet字段里也不包含视频类别ID,导致你没法直接过滤。
下面是一个更优雅的解决方案,不需要多次重复查询,只需要两步就能拿到符合要求的10条结果:
核心思路
- 先一次性搜索比目标数量多的结果(比如20条),确保过滤后能凑够10条;
- 批量调用
Videos.list接口,获取这些视频的类别ID; - 过滤掉属于要排除类别(比如恐怖类39)的视频,取前10条即可。
Python代码实现
首先确保你安装了Google API客户端库:
pip install google-api-python-client
然后是完整代码:
from googleapiclient.discovery import build # 替换成你的YouTube Data API密钥 API_KEY = "YOUR_API_KEY_HERE" # 要排除的类别ID(恐怖类是39) EXCLUDED_CATEGORIES = {"39"} # 目标结果数量 TARGET_RESULTS = 10 # 预搜索的结果数量(建议比目标多,防止过滤后不够) PRE_SEARCH_COUNT = 20 def search_videos_exclude_category(query): youtube = build('youtube', 'v3', developerKey=API_KEY) # 第一步:搜索视频,获取基础信息和ID search_response = youtube.search().list( q=query, type='video', part='id,snippet', maxResults=PRE_SEARCH_COUNT ).execute() # 提取所有视频ID video_ids = [item['id']['videoId'] for item in search_response['items']] # 第二步:批量获取视频的类别信息 videos_response = youtube.videos().list( id=','.join(video_ids), part='snippet' ).execute() # 构建视频ID到类别ID的映射 video_category_map = { item['id']: item['snippet']['categoryId'] for item in videos_response['items'] } # 第三步:过滤掉排除类别的视频,取前TARGET_RESULTS条 filtered_results = [] for item in search_response['items']: video_id = item['id']['videoId'] category_id = video_category_map.get(video_id) if category_id not in EXCLUDED_CATEGORIES: filtered_results.append(item) if len(filtered_results) == TARGET_RESULTS: break return filtered_results # 调用示例 results = search_videos_exclude_category("The ring") for idx, result in enumerate(results, 1): print(f"{idx}. {result['snippet']['title']}")
关键点说明
- 预搜索数量设置:设置
PRE_SEARCH_COUNT为20是因为大部分情况下,过滤后能留下足够的结果;如果你的搜索词大部分都属于排除类别,可以适当提高这个数值(比如30),避免循环查询。 - 批量查询优化:通过
','.join(video_ids)一次性查询多个视频的类别信息,减少API调用次数,提升效率。 - 类别判断:用集合存储排除的类别ID,
category_id not in EXCLUDED_CATEGORIES的判断效率更高。
如果遇到极端情况(比如预搜索的结果全是排除类别),可以再加入循环逻辑,继续搜索下一页结果直到凑够目标数量,但这种情况很少见。
内容的提问来源于stack exchange,提问作者Huevo Podrido
相关产品推荐
相关产品推荐

