YouTube Shorts 趋势研究 API:Python 实战

用 YouTube Shorts 搜索、分页、视频详情、频道样本和评论接口搭建可审计的趋势研究流程。

深色研究时间线把 YouTube Shorts 信号整理成趋势和观众问题

YouTube Shorts 趋势研究最常见的误区,是把搜索结果按播放量一排就称为「趋势」。这种做法忽略发布时间、带 K/M 后缀的字符串、频道自身基线,以及观众真正反复追问的问题。本文使用 SandBase YouTube API 目录里的公开接口,完成搜索、翻页、标准化、短名单补全和证据留存。

实测完成于 2026 年 10 月 25 日(UTC),关键词为 “AI agents”。嵌套字段是当日观察,不代表永久 Schema。需要从频道出发时,可读 YouTube 频道研究 API 指南。

先说结论

  • 搜索结果可能返回 5.8K views 这样的字符串,排序前必须解析,同时保留原值。
  • 本次翻第二页时,continuation_token 必须和原关键词一起发送。
  • this_month + view_count 的实测组合返回空列表;空结果也是数据,不能悄悄换条件补结果。
  • 视频详情、评论和频道 Shorts 只补全短名单,避免把调用浪费在全部候选上。

接口实际返回了什么

无附加过滤的搜索返回 shorts 数组、原关键词和 continuation token。第一条含 video_id、标题、URL、缩略图及格式化播放量;作者和频道字段存在但为空,因此程序不能假设搜索一定给出频道身份。

YouTube Shorts 搜索第一条结果 搜索适合发现,但格式化计数必须先标准化。

第一次只发送 token 请求第二页,接口返回 HTTP 400;把原关键词和同一个 token 一起发送后成功,并返回新的 token。这个规则应进入任务状态和回归测试。

YouTube Shorts 翻页时需要保留原关键词 本次实测中,第二页需要关键词与 continuation token 同时出现。

评论接口返回评论数组及自己的 token。它适合在确定短名单之后补充定性需求信号,例如重复出现的使用问题。

YouTube 评论结果与分页令牌 评论能补充播放量无法表达的问题,但应限制样本并保留出处。

安装和鉴权

python -m pip install requests
export SANDBASE_API_KEY="your_key_here"
import os, time, requests
BASE = "https://api.sandbase.ai/v1/api"
HEADERS = {"Authorization": f"Bearer {os.environ['SANDBASE_API_KEY']}",
           "Content-Type": "application/json"}

def call(model, payload, retries=2):
    for attempt in range(retries + 1):
        r = requests.post(f"{BASE}/{model}", headers=HEADERS,
                          json=payload, timeout=90)
        if r.status_code < 500 and r.status_code != 429:
            r.raise_for_status(); break
        if attempt == retries: r.raise_for_status()
        time.sleep(2 ** attempt)
    body = r.json()
    if body.get("status") != "completed":
        raise RuntimeError(body.get("error") or body.get("status"))
    try: return body["outputs"][0]["data"]
    except (KeyError, IndexError, TypeError) as exc:
        raise RuntimeError("Missing outputs[0].data") from exc

搜索并保留分页上下文

def search_shorts(keyword, pages=2, sort_by=None, upload_date=None):
    token, rows, seen = None, [], set()
    for _ in range(pages):
        payload = {"keyword": keyword}
        if sort_by: payload["sort_by"] = sort_by
        if upload_date: payload["upload_date"] = upload_date
        if token: payload["continuation_token"] = token
        page = call("youtube/web-v2/shorts-search-v2", payload)
        for item in page.get("shorts") or []:
            video_id = item.get("video_id")
            if not video_id or video_id in seen: continue
            seen.add(video_id); rows.append(item)
        token = page.get("continuation_token")
        if not token: break
    return rows

筛选结果为空时不要自动放宽条件。先记录空结果,再运行一个明确标注为「宽泛查询」的新任务。本次严格查询虽然 shorts 为空,仍返回了 token,正好说明不能仅凭某个字段判断页面有效性。

解析播放量字符串

import re
def parse_count(value):
    if isinstance(value, int): return value
    if not value: return None
    text = str(value).upper().replace(",", "")
    match = re.search(r"([0-9]+(?:\.[0-9]+)?)\s*([KMB]?)", text)
    if not match: return None
    scale = {"": 1, "K": 1_000, "M": 1_000_000, "B": 1_000_000_000}
    return int(float(match.group(1)) * scale[match.group(2)])

原始字符串也要保存。如果 YouTube 改变语言或格式,之后才能审计解析器为什么得出某个数。

只给短名单补详情

def enrich(video_id, channel_id=None):
    info = call("youtube/web-v2/video-info-v2", {"video_id": video_id})
    comments = call("youtube/web-v2/video-comments", {
        "video_id": video_id, "sort_by": "top",
        "need_format": True, "language_code": "en",
    })
    channel = None
    if channel_id:
        channel = call("youtube/web-v2/channel-shorts", {
            "channel_id": channel_id, "need_format": True
        })
    return {"info": info, "comments": comments.get("comments") or [],
            "channel_shorts": channel}

频道补全必须是条件式的:首条搜索结果的频道 ID 为空,本次视频详情响应也只观察到 publish_date、rating、thumbnail_url 和 video_id。没有 ID 就跳过,不能从标题猜一个频道。

另一次独立检查使用 OpenAI 的公开频道 ID,确认 channel-shorts 可以完成;这不代表前述搜索结果属于 OpenAI。如果能取得频道样本,应把单条 Shorts 与固定窗口的频道中位数比较。只有 publish_date 能可靠解析时才加入新鲜度。评论主题与量化分数应分开:可以用大模型聚类一个有上限的评论样本,但输出必须指向原评论位置。

参数速查

接口必填常用可选项分页
shorts-search-v2首次请求的 keyword排序、上传时间、token返回 continuation token
channel-shortschannel_id 或 channel_urlneed_format、token返回 continuation token
video-info-v2video_id 或 video_urlneed_format无
video-commentsvideo_id排序、语言、国家、token返回 continuation token

生产环境护栏

把查询、筛选条件、token、抓取时间和解析器版本一起保存。限制页数与评论样本数。429、5xx 和短暂网络故障可以退避重试;400 应进入人工检查,因为静默改查询会改变研究问题。空字符串视为不可用 ID。日志不能包含 API Key 或临时媒体 URL。

报告应写成「该查询在该时间的高位结果」,不要扩张成全 YouTube 趋势。搜索本来就依赖查询词,排序系统也会变化。可以运行多个相邻问题,找反复出现的主题,并把采样视频 ID 留给审核者。

常见问题

  • 第二页返回 400:同时发送原关键词和 continuation token。
  • 筛选后为空:保留记录,再创建单独命名的宽泛查询。
  • 播放量排序错误:先解析 K/M/B 后缀,并保存原始字符串。
  • 频道 ID 为空:跳过频道补全,不能从标题推断。
  • 没有评论:把样本量记为 0,不要让模型补出主题。

这能发现全 YouTube 的所有趋势吗?

不能。它只对明确查询返回的证据排序。平台级结论需要更广的采样和公开的方法说明。

评论可以直接拿来训练吗?

这套流程用于公开研究。任何超出聚合分析的复用,都应先检查权利、条款、留存和隐私要求。

当前参数去哪里确认?

以 YouTube API 目录的实时 Schema 与可用状态为准。