频道 1.8 万条视频,我用 yt-dlp 批量拉字幕时把限速当成了封号
手上有个做知识区的频道,1.8 万条视频,大部分有自动字幕。我想把字幕拉下来做本地全文搜索,环境是 Ubuntu 22.04,yt-dlp 2024 年某个版本(具体版本号没记,用 pip 装的),Python 3.10 调用 subprocess 循环跑。
第一版写得很直白,按视频 ID 列表逐条跑:
yt-dlp --skip-download --write-auto-subs --write-subs \
--sub-langs "zh-Hans,en" --sub-format vtt \
--sleep-requests 1 --sleep-interval 3 \
-o "%(id)s.%(ext)s" \
--batch-file ids.txt
跑了两千多条后开始出现大量 HTTP Error 429,随后部分请求返回空字幕文件,但退出码还是 0。这个最坑:脚本以为成功了,实际上写了个 0 字节的 vtt。我后来加了一个落盘检查,凡是文件大小小于 200 字节的直接删掉重试,重试上限三次。
429 的原因是我把 --sleep-requests 设成 1 秒,但请求字幕的接口和请求视频页面的接口节奏不是一回事,自动字幕的请求密度比我想的高。改成 --sleep-requests 2.5 --sleep-interval 6 之后 429 基本消失,代价是整批拉完要十几个小时。我接受这个代价,因为重跑一次的成本更高。
另一个坑是 --sub-langs。频道里有不少视频只有 zh-Hant 和 en,我一开始只写 zh-Hans,en,那些视频直接没输出,也不报错。后来用 --list-subs 抽样看了二十条,才发现语言代码不止一种写法。现在我的做法是先跑一遍 --list-subs 存成清单,按清单决定每条视频要哪些语言,而不是全局写死。
还有个小问题:自动字幕的 vtt 里大量重复行和滚动式时间戳,直接 grep 会命中一堆碎片。我是在入库前用一段 Python 去重相邻重复行,效果一般,但够用。
边界条件也说一下:私有视频、会员专属视频、地区限制视频,这几种 yt-dlp 拿不到字幕,会混在失败列表里,别把它们当脚本 bug 去查。另外,频道早期有几百条视频压根没有字幕,包括自动生成的也没有,这部分只能放弃。
现在的问题是我还没想清楚怎么判断「字幕拉全了」——视频总数、有字幕的视频数、成功落盘数这三个数字对不上时,到底该以哪个为准。你们做类似归档时是怎么做完整性校验的?
0 条评论
还没有评论,写下第一条。