频道 400 条视频的播放列表,我用 yt-dlp 抓完发现少了 37 条

频道有 400 条视频,我按播放列表抓元数据,跑完之后库里只有 363 条。不是解析失败,yt-dlp 退出码是 0,日志里也没报错。第一次遇到这种情况,我以为是过滤条件写错了。

环境是 yt-dlp 2024 年某个版本(不确定具体小版本,一直跟着 pip 更新),Python 3.11,Linux。命令大致是这样:

yt-dlp --flat-playlist --dump-json \
  "https://www.youtube.com/playlist?list=PLxxxxxxxx" \
  > pl.jsonl
wc -l pl.jsonl   # 363

我拿频道页的 video count 对比,400 对 363。差 37 条。

做法上我分了两步排查。先确认是不是 flat 模式的问题:flat-playlist 只拿列表页里已有的条目,不逐条进入视频页,理论上条目数应该和页面一致。然后我把 --flat-playlist 去掉重跑,条数还是 363,说明不是 flat 的锅。

第二步是逐条比对。我把频道页按时间倒序滚动到最底部,手动记下最后 40 条的 ID,再和 pl.jsonl 里的 id 集合做差集:

import json

with open("pl.jsonl") as f:
    got = {json.loads(l)["id"] for l in f if l.strip()}

# 手动从频道页抄的最后 40 个 ID
manual = {...}
missing = manual - got
print(len(missing), missing)

差的 37 条集中在两个位置:一部分是频道里非常老的视频(大概 2013 年以前),另一部分是几个成员限定或已设为不公开的条目。老视频那条更隐蔽——它们在频道页能看见,但不在这条播放列表里。我后来才意识到:我抓的是频道自动生成的 uploads 播放列表,而它并不是频道全部视频的完整镜像,早期视频有时会漏。

所以机制上的取舍是:flat-playlist 快,一次请求拿一页,400 条几秒就完;但它信任的是列表本身,列表不全,结果就不全。去掉 flat 逐条抓能拿到更多字段,但 400 条要发 400 次请求,速度慢一个量级,还更容易触发限流。我的判断是:做元数据盘点时,条数对不上比字段缺失更致命,所以宁可慢。

边界条件也说清楚。这个方法对公开频道有效,对成员限定内容无效;频道页的 video count 本身也可能因为地区、登录状态而不一致,我这次是对着未登录状态数的。另外 uploads 列表漏老视频这件事,我没找到稳定规律,只能说别默认它等于全集。

现在我的做法是先 flat 抓一遍拿到 ID 集合,再用频道页做一次差集校验,缺的补抓。校验脚本比抓取脚本长,但值得。

你们抓频道全集时,是用 uploads 播放列表,还是从频道页翻页拿 ID?差集一般差多少条?

0
赞同度 100% · 0 条评论 · 3 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。