视频号下载 Skill:从公开 API 到双源容灾
几天前在 Hermes Agent 里跑通了零 cookie 视频号下载,最近把它封装成了一个标准的 WorkBuddy Skill,过程中遇到上游 API 宕机,顺便实现了双源自动容灾。
一、从零散脚本到标准化 Skill
之前的方案是单文件 Python 脚本,依赖一个固定的解析 API:
https://sph.litao.workers.dev/api/fetch_video_profile做成 WorkBuddy Skill 后,结构变成:
wxchannel-download/
├── SKILL.md # 技能定义:触发词、使用方式、技术原理
└── scripts/
└── download.py # 双源容灾下载脚本SKILL.md 声明了触发词:
- 视频号下载、下载视频号、微信视频号
- channels download、weixin.qq.com/sph 链接下载
这样 Agent 看到用户发来 https://weixin.qq.com/sph/xxx 时说"下载这个视频",就会自动加载 Skill 并执行。
二、问题定义
用户发来视频号分享链接:
https://weixin.qq.com/sph/AJWTtY9aHw期望:拿到原始 MP4 + 标题 + 作者 + 互动数据。
三、常见思路为什么不行
视频号是微信封闭生态。第一反应就是 cookie / 抓包 / 协议逆向。
| 方案 | 缺陷 |
|---|---|
| 元宝 cookie | 每次失效要重新 F12 抓,门槛高 |
| 微信 PC 客户端 + mitmproxy | 需安装证书 + 保持微信运行 |
| 逆向 iPad / Mac 协议 | 工作量大、易风控 |
| 商业 API (xbot / 个微) | 几百到几千元/月 |
这些都能跑通,但都不是最小可行方案。
四、关键转折:找到一个公开服务
搜 GitHub 时注意到项目 ltaoo/sph.litao.workers.dev,是个 Cloudflare Workers 部署的网页工具,提供"视频号视频信息查询"。
直接看网站源码找端点:
const API_BASE = "/api";
fetch(`${API_BASE}/fetch_video_profile`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ url: shareUrl }),
})一个干净的 POST 接口,没看到任何鉴权 header。
验证:
curl -X POST https://sph.litao.workers.dev/api/fetch_video_profile \
-H "Content-Type: application/json" \
-d '{"url": "https://weixin.qq.com/sph/AJWTtY9aHw"}'返回包含 videoUrl(腾讯 CDN 直链),包含签名但不需要 cookie。零 cookie、零鉴权、零限制。
五、为什么这个 API 能存在?
- ltaoo 一定有自己的 cookie(存在 Workers 后端 KV 里),所有用户共享
- 它的前端只做两件事:收集链接 → 转给后端 → 展示元数据
- 后端用某个 cookie 调元宝 / finder-preview / 第三方 API
- 关键是它把 cookie 隐藏在服务端了,公开端点不要求 cookie
这种"代理"模式在企业里叫 BFF (Backend for Frontend)。
六、踩坑记录
坑 1:先查了 bykj.top 的源码
我带 CORS 代理的纯前端工具,但 Python 服务端调用没有 CORS 问题!直接调 sph.litao.workers.dev 即可。
坑 2:cookie 不对也跑通了"元数据"
ltaoo 公开端点不需要任何 cookie,但我一开始绕远路去抓元宝 cookie,撞了 401。别让"最显眼的方案"挡住最简单的路径。
坑 3:JS 混淆压缩挖不到 URL
用 curl 抓视频号预览页的核心 JS 想找 API,反混淆后只找到模板字符串,export_id 完全没出现——分享链接 → export_id 的转换完全在后端。
坑 4:Python urllib 不自动带 User-Agent
脚本写好测试时,解析 API 返回 Cloudflare 403(error code: 1010)。原因是 Python urllib.request 不会自动设置浏览器 User-Agent,被 CF 反爬拦截了。加上:
req.add_header("User-Agent", "Mozilla/5.0 ...")问题解决。
七、服务宕机 → 双源容灾
Skill 做好几个小时后,用户要求下载另一个视频:
https://weixin.qq.com/sph/AtqTRbMHny结果 litao 的 Workers 服务连接超时——sph.litao.workers.dev 完全不可达。
寻找替代方案
搜索引擎找到 bugpk.com 的聚合解析接口(开源项目 jiuhunwl/short_videos),支持 20+ 平台,包括视频号:
GET https://api.bugpk.com/api/short_videos?url=<share_url>试了一下:
{
"code": 200,
"msg": "解析成功",
"data": {
"type": "video",
"title": "千万不要在小环境里待太久...",
"author": { "name": "个人提升宝典" },
"cover": "https://finder.video.qq.com/...",
"url": "https://finder.video.qq.com/251/20302/stodownload?...",
"quality": "1080p",
"video_backup": [
{ "label": "1080p", "codec": "h264", "url": "..." },
{ "label": "1080p", "codec": "h265", "url": "..." }
]
}
}同样是零 cookie、无需鉴权,而且直接提供了 h264/h265 编码区分,响应格式比 litao 的更规范。
双源容灾实现
在脚本中定义解析 API 列表,按优先级依次尝试:
PARSE_APIS = [
{
"name": "bugpk",
"url": "https://api.bugpk.com/api/short_videos",
"method": "GET",
"response_parser": "bugpk",
},
{
"name": "litao",
"url": "https://sph.litao.workers.dev/api/fetch_video_profile",
"method": "POST",
"response_parser": "litao",
},
]每个 API 有独立的响应解析器,统一输出标准化的视频信息字典。parse_share_url 函数自动遍历,首个成功即返回,全部失败才报错。
实测验证
升级后的 Skill 成功解析并下载了多个视频:
| 视频 | 作者 | 画质 | 大小 |
|---|---|---|---|
| 虚拟资料怎么做 | 温少创业记 | 原始 | 38 MB |
| 千万不要在小环境里待太久 | 个人提升宝典 | 1080p | 10.5 MB |
八、最终脚本核心
class Downloader:
"""双源容灾,自动 failover"""
PARSER_MAP = {
"bugpk": self._parse_bugpk,
"litao": self._parse_litao,
}
def parse(self, share_url):
for api in PARSE_APIS:
try:
data = self._call_api(api, share_url)
return self.PARSER_MAP[api["name"]](data)
except Exception as e:
last_error = e
continue
raise RuntimeError(f"所有 API 均失败: {last_error}")
def download(self, video_url, output_path):
req = urllib.request.Request(video_url)
req.add_header("Referer", "https://channels.weixin.qq.com/")
with urllib.request.urlopen(req, timeout=300) as resp:
with open(output_path, "wb") as f:
while chunk := resp.read(256 * 1024):
f.write(chunk)完整脚本在 Skill 包中:~/.workbuddy/skills/wxchannel-download/scripts/download.py
九、关键经验
- 先找"对的产品",再写代码。ltaoo 那个项目花 5 分钟读 README 就找到了;bugpk 花 2 分钟搜索就找到了。
- 公开接口可能真的公开。CORS 是浏览器限制,不是 API 限制。服务端调用无需代理。
- 不要从最复杂的方案开始。元宝 cookie / 抓包 / 协议逆向都是"答案",但不是最小答案。
- 第三方服务随时会挂,做好容灾。只上了一天就遇到 litao 宕机,没有备用方案就尴尬了。
- 踩过的坑要固化。Python
urllib不带 UA 被 CF 拦截、Referer 头必须设置——这些都是做 Skill 时需要写进脚本的。 - Skill 高于脚本。单独的 Python 文件只是工具;包装成 Skill(SKILL.md + scripts + 触发词)才能让 Agent 自动识别和调用。
十、依赖与风险
- 双源(降低了单点故障):bugpk.com 主 + sph.litao.workers.dev 备,任一可用即可
- 速率限制:建议单次批量不超过 50 条/小时
- 风控:后端 cookie 池可能被腾讯风控
- 终极备用:可自行部署 ltaoo/sph.litao.workers.dev 或 jiuhunwl/short_videos
十一、延伸应用
拿到视频后能做什么:
- 转字幕:
ffmpeg -i video.mp4 -vn -acodec pcm_s16le -ar 16000 audio.wav+ Whisper 转录 - 截图首帧:
ffmpeg -i video.mp4 -ss 0 -vframes 1 cover.jpg - 压缩:
ffmpeg -i video.mp4 -c:v libx264 -crf 28 -c:a aac small.mp4 - 自动化工作流:视频号分享链接 → Skill 解析下载 → 元数据入库 → 内容转写分析