先说说这事儿咋来的
前两天帮媳妇做年终汇报PPT,她用的那个叫“ppt365”的在线工具,里面想嵌一段产品演示视频,找半天,发现百度视频搜索结果页里那个预览片段正合适,问题是——ppt365只认本地文件或直链,不支持直接抓取网页里的视频流,媳妇一句“你搞技术的,这点小事还用我教?”彻底把我架住了。
行吧,用Go写个小工具,这活儿比想象中坑多,但也就一下午,今天把完整思路记下来,下次有人再问“ppt365里怎么抓百度视频”,直接甩这篇。
抓取前必须搞懂的三件事
百度视频的URL不是你以为的那个URL
打开百度视频搜索“无人机评测”,地址栏一串https://v.baidu.com/...,表面看是视频页面,实际加载是个SPA(单页应用),真正的视频源藏在一个videoInfo的JSON接口里,这接口每次请求带时间戳签名,直接HTTP GET是拿不到的。
视频源分三六九等
百度视频返回的m3u8列表里,有1080p、720p、480p三个档位,还分mp4直链和hls切片流,ppt365插入时,只认mp4直链,或者能直接内嵌的iframe代码,HLS流插进去白屏,别问我怎么知道的。
反爬机制就三板斧
- User-Agent:必须伪装成Chrome最新版
- Referer:必须带百度视频的完整来源页
- Cookie:有时需要新鲜的那条
BAIDUID
这三样少了哪个,返回的都是乱码加密的JSON。
实战:一步步用Go把视频“抠”下来
第一步:构造带签名的搜索请求
百度视频的搜索接口其实是https://v.baidu.com/s?word=关键词&format=json,但直接请求大概率返回空数据,因为少了个关键的pn参数(页码),我用Go的net/url包手动拼参数:
func buildSearchURL(keyword string, page int) string {
u, _ := url.Parse("https://v.baidu.com/s")
q := u.Query()
q.Set("word", keyword)
q.Set("pn", strconv.Itoa(page*10))
q.Set("rn", "10")
q.Set("format", "json")
u.RawQuery = q.Encode()
return u.String()
}
注意,pn从0开始,每页10条,这步拿到的JSON里,result数组的每个元素带vid字段,这就是后面要用的视频唯一ID。
第二步:从搜索结果反查视频源地址
拿到vid后,真正的视频信息在另一个接口:https://v.baidu.com/video/player/api?vid=xxx&type=json,但这接口返回的videoList是加密的,得用common包里的AES解密,坑就在这里——解密密钥每天变。
我临时写了个workaround:先请求页面拿到一份JS(https://v.baidu.com/static/js/player.js),用正则抽出里面的key变量,这法子不优雅,但当天能用。
// 伪代码,重在思路
resp := get(playerJS)
keyPattern := regexp.MustCompile(`"key"\s*:\s*"([a-f0-9]{16})"`)
key := keyPattern.FindStringSubmatch(resp)[1]
// 然后用这个key去AES-CBC解密videoList字段
| 请求对象 | 关键参数 | 加密情况 | |
|---|---|---|---|
| 搜索接口 | word, pn, rn | 视频列表(含vid) | 无 |
| 播放器接口 | vid, type | 视频源(加密) | AES,密钥在JS中 |
| 视频直链 | 无(需从上面提取) | mp4/hls地址 | 有时带有效期签名 |
第三步:挑出适合ppt365的视频源
解密后拿到一个JSON数组,每个元素像这样:
{
"type": "mp4",
"url": "http://vd2.bdstatic.com/...",
"resolution": 720,
"duration": 128
}
ppt365插入视频,优先选mp4格式,分辨率720p以上,因为1080p的源有时是HLS,而mp4直链嵌进去最省事,我写了个过滤函数:
func pickBestSource(sources []VideoSource) *VideoSource {
for _, s := range sources {
if s.Type == "mp4" && s.Resolution >= 720 {
return &s // 一旦找到就返回,不贪心
}
}
// 没有完美源,退而求其次选HLS里码率最高的
return &sources[len(sources)-1]
}
第四步:下载并转码(如果必要)
mp4直链就直接http.Get拉流存本地,但百度视频的mp4链接有过期时间,大概2小时,下载时记得加Range: bytes=0-头,断点续传。
如果是HLS源,就麻烦点:需要解析.m3u8文件,逐个下载.ts切片,再用ffmpeg合并转mp4,Go的github.com/grafov/m3u8库能解析,但转码还得调外部程序。
cmd := exec.Command("ffmpeg", "-i", "input.m3u8", "-c", "copy", "output.mp4")
cmd.Run()
这步不是纯Go,但实用,你说“纯Go”当然是骗媳妇的,她又不看代码。
插进PPT365的正确姿势
拿到本地mp4文件后,ppt365支持的插入方式有三种:
- 上传文件:直接拖进去,但文件不能超过200MB
- 外链地址:填一个公网可访问的URL,ppt365会实时拉流
- iframe嵌入:把视频页面嵌进去,但百度视频不让
最稳的是第二种——如果你恰好有个云存储或临时图床,用Go的net/http写个简单文件服务器暴露几分钟,PPT上加载完再关掉。
http.Handle("/", http.FileServer(http.Dir("./videos")))
http.ListenAndServe(":8080", nil)
然后把http://你的IP:8080/xxx.mp4填到ppt365的“在线视频”框里,这法子唯一的缺点是,PPT演示时需要网络,且公网IP得通透,本地演示就当我没说。
绕不开的坑与填坑姿势
坑一:请求头少了Accept-Language
用Go默认的http.Client请求百度视频,会返回403,后来发现得带上:
Accept-Language: zh-CN,zh;q=0.9
加上之后立马通,这年头服务器都看人下菜碟。
坑二:解密后的视频URL是相对路径
解密的JSON里url字段有时是//vd2.bdstatic.com/...,少了http:前缀,直接拿去找ppt365,它不认,Go里处理很烦,但就一行:
if strings.HasPrefix(u.Url, "//") {
u.Url = "https:" + u.Url
}
坑三:ppt365对视频编码有要求
默认下载的百度视频多是h264编码,能插,但偶尔遇到h265的720p源,PPT插入后声音和画面不同步,我后面学了点ffmpeg参数,遇到非h264强制转:

ffmpeg -i input.mp4 -vcodec libx264 -acodec aac -strict experimental out.mp4
转完立马正常,这事儿怪百度,不怪ppt365。
顺手把抓取写成了个小工具
写到最后,顺手封装成了一个命令行的CLI小工具,叫 bdv,用起来很简单:
bdv -keyword "无人机评测" -page 1 -output ./video.mp4
内部逻辑就是我上面写的那些,再加了个--format mp4和--quality 720p的参数,这个工具在本地用完全没问题,但要小心别高频请求百度,否则IP被封也无话可说。
代码核心就200多行,有点糙,但够用。没做并发,没做重试,因为就逮着一个视频下载,没必要复杂化,你要是想跑大规模下载,自己改吧,记得遵守robots.txt。
说点关于版权的话
抓百度的视频,技术上可行,但版权上要慎重,我这次抓的是自家公司拍的宣传片,公开放出来的,如果视频属于第三方,下载完了插PPT里自己同事看看倒还行,分发出去就惹麻烦了,建议下载前先看下视频页有没有“禁止下载”标记,或者搜下作者授权声明,反正我是不鼓励把这工具用在盗版视频上的。
用Go抓百度视频这活儿不算难,但折腾人的地方在于各种头文件、加密、过期链接,我也是边试边错,用了一个下午,好在结果是好的,媳妇PPT按时交了,还夸我“这次没掉链子”,我心里想:那是你没看见我对着ffmpeg报错日志抓耳挠腮的样子。
工具代码就不贴全文了,上面关键片段都放了,如果你有问题可以直接试,反正Go的语法就那样,跑起来报错看堆栈,改一行继续跑。不要问我为什么百度那个JS密钥每天变,这个问题我打算跟百度后台程序员聊聊人生。
本文来自作者[kyadmin]投稿,不代表be365立场,如若转载,请注明出处:http://hljbesthome.com/nba/2497.html
评论列表(4条)
我是be365的签约作者“kyadmin”!
希望本篇文章《用Golang扒下百度视频,从PPT365到本地硬盘的折腾手记》能对你有所帮助!
本站[be365]内容主要涵盖:be365,be365网站,be365网址,ball365体育,Be365排名
本文概览:先说说这事儿咋来的前两天帮媳妇做年终汇报PPT,她用的那个叫“ppt365”的在线工具,里面想嵌一段产品演示视频,找半天,发现百度视...