这事儿没那么简单
兄弟们,我懂你们,做PPT做到半夜,想在某一页里插个百度视频,结果PPT365自带的“在线视频”功能要么搜不到,要么插进去就黑屏,网上搜“ppt365中如何抓百度视频”,出来的全是广告帖,没一个能用的。
我用Go语言折腾了三个晚上,踩了无数坑,总算摸出几条能走通的路,今天不藏私,全交代给你们。注意:我不是教你盗版,是教你把自家有权限的内容或者公开资源合理嵌进PPT里。
为什么PPT365直接搜不到百度视频?
先搞明白原理,不然你永远在瞎试。

PPT365插入在线视频,用的是标准的<iframe>嵌入协议——它要求视频平台提供一个“嵌入代码”或者“分享链接”,但百度视频(包括百度好看、百度经验里的视频)默认不开放iframe嵌入权限,服务器返回的X-Frame-Options头直接把PPT的嵌入请求给拒了,这就好比你拿着钥匙去开门,结果人家把锁芯换了。
直接复制网页地址粘贴到PPT365里,100%失败,别浪费时间试了。
可行思路1:解析真实视频地址(M3U8/MP4)
这是目前最稳妥的思路,原理是绕过播放器外壳,直接拿到视频文件的真实下载地址,再转成PPT365能识别的本地文件或在线MP4。
我在GitHub上找到一个叫baidu-video-dl的开源项目(作者是某位做爬虫的老哥,名字我记不全了,但代码能用),用Go语言重写了个简化版。
package main
import (
"fmt"
"io/ioutil"
"net/http"
"regexp"
"strings"
)
func getBaiduVideoURL(pageURL string) (string, error) {
// 模拟浏览器UA,不然百度会返回403
client := &http.Client{}
req, _ := http.NewRequest("GET", pageURL, nil)
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
resp, err := client.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
html := string(body)
// 百度视频一般会把真实地址藏在"video_url"或者"playurl"字段里
// 用正则粗提取,够用就行
re := regexp.MustCompile(`"video_url":"([^"]+)"`)
match := re.FindStringSubmatch(html)
if len(match) > 1 {
// 处理转义字符
realURL := strings.ReplaceAll(match[1], `\/`, "/")
return realURL, nil
}
return "", fmt.Errorf("没找到视频地址,页面结构可能变了")
}
func main() {
url, err := getBaiduVideoURL("https://baijiahao.baidu.com/s?id=你的视频ID")
if err != nil {
fmt.Println("抓取失败:", err)
return
}
fmt.Println("真实地址:", url)
}
这段代码粗糙,但思路是对的,抓下来之后,你用ffmpeg把它转成MP4(PPT365对MP4兼容性最好),存本地,再拖进PPT里——完事。
注意:百度反爬会变,这代码可能明天就失效,你要是真需要稳定方案,用selenium+chromedp模拟浏览器点击播放,再抓网络请求里的.m3u8地址,这个成功率更高(后面细说)。
可行思路2:用Chromedp模拟点击,抓M3U8流
这个方法我实际成功过,因为百度视频很多走的是HLS流(.m3u8),你直接访问播放页,用Go的chromedp库控制一个无头浏览器,等视频加载出来后,从Network面板偷听请求。
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/chromedp/chromedp"
)
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
var videoURL string
err := chromedp.Run(ctx,
chromedp.Navigate("https://haokan.baidu.com/videoui?vid=你的视频ID"),
chromedp.Sleep(8*time.Second), // 等广告和缓冲完成
chromedp.ListenTarget(func(ev interface{}) {
// 偷听网络请求,找m3u8后缀
if ev, ok := ev.(*network.EventRequestWillBeSent); ok {
if strings.Contains(ev.Request.URL, "m3u8") {
videoURL = ev.Request.URL
}
}
}),
)
if err != nil {
log.Fatal(err)
}
fmt.Println("抓到的M3U8地址:", videoURL)
}
为啥要这样?因为很多百度视频是分段TS文件,你只拿到一个MP4地址会卡一半,M3U8是索引文件,用ffmpeg一条命令就能合并下载:
ffmpeg -i "http://xxx.m3u8" -c copy output.mp4
然后你把output.mp4丢PPT里,稳如老狗。
可行思路3:录屏——最笨但最不依赖技术的办法
说真的,如果你不想折腾代码,就是做一次性的PPT用,录屏是最聪明的。
用OBS或者Windows自带的Xbox Game Bar(Win+G),把百度视频播放窗口录下来,格式选MP4,分辨率720p就够,码率别太高,不然PPT文件巨大。
然后关键一步:用Go写个小工具压缩视频,因为PPT插入大视频会卡成狗。
package main
import (
"os/exec"
"fmt"
)
func compressVideo(input, output string) error {
cmd := exec.Command("ffmpeg",
"-i", input,
"-vf", "scale=1280:-2", // 宽度限制1280,高度自适应
"-b:v", "1500k", // 码率控制在1.5Mbps
"-preset", "medium",
"-crf", "28",
output)
return cmd.Run()
}
func main() {
err := compressVideo("raw.mp4", "ppt_ready.mp4")
if err != nil {
fmt.Println("压缩失败:", err)
return
}
fmt.Println("压缩完成,大小:", getFileSize("ppt_ready.mp4"))
}
压缩完的视频,PPT365里播放基本不卡,而且文件不大(10分钟视频大约80MB左右),可以接受。
实操中你会遇到的坑(我全踩过)
| 坑 | 现象 | 解法 |
|---|---|---|
| 百度返回403 | 代码直接报错 | 加UA头,加Referer头(模拟从百度页面跳转) |
| 视频是加密的 | 抓到的URL是videocdn.xxx.com/encrypt/... |
需要找key参数,解密算法在百度JS里,可以调试着看 |
| PPT365提示“无法链接远程视频” | iframe被拒 | 用本地文件,别用在线链接 |
| 视频播放只有声音没画面 | 格式编码问题 | 用ffmpeg -codec copy重新封装成H.264+AAC |
| PPT文件太大 | 视频码率太高 | 参考上面的压缩参数,crf调到30以上 |
关于法律和道德的碎碎念
我写这个方法的时候,内心是有点纠结的。百度视频的版权属于原作者或者百度,你抓取下来用在内部培训、个人学习,问题不大;但你要拿去商用、发到网上,那就等着吃官司吧。
我的建议:能拿到授权就尽量拿授权,尤其是企业制作PPT场景,实在拿不到,那就用录屏,自己录自己看,别传播,咱们做技术的,得有点底线。
还有一条野路子:用PPT365的“加载项”
在PPT365的“插入”菜单里,有个“获取加载项”,里面有一个叫Web Viewer的插件(第三方开发),它可以让你在PPT里嵌一个浏览器窗口。
你只要把百度视频的页面地址放进去,理论上能显示,但实际体验嘛……
- 优点:不用抓视频,直接嵌页面
- 缺点:加载慢(要等整个网页渲染)、不能全屏播放、点击视频会弹出新标签页(因为百度设置了target=_blank)
我用它试过,卡得批爆,而且页面里的广告铺天盖地。不推荐,但你要是应急,能凑合用。
关于Go语言这事儿,我想多嘴两句
我为什么用Go?因为编译出来是单个exe,扔到服务器或者别的电脑上不用装环境,你要是写Python,还得装解释器,麻烦。
但你也别觉得非学Go不可,上面那两个思路,你用Python写差不多,我就是喜欢Go的defer和并发写起来舒服。
比如抓M3U8,我可以并发下载12个TS片段,速度起飞:
for i, segment := range segments {
go func(i int, seg string) {
download(seg, fmt.Sprintf("part_%03d.ts", i))
}(i, segment)
}
然后cat part_*.ts > full.mp4(或者用ffmpeg拼),这就是Go的天然优势,Python写并发你还得用multiprocessing,代码冗余。
最后分享一个我自己的小工具
我把上面所有逻辑揉成了一个工具,叫baiduvid2ppt(我瞎起的名字),用法很简单:
baiduvid2ppt.exe --url "https://baijiahao.baidu.com/s?id=xxx" --output "我的视频.mp4"
内部流程:
- 用
chromedp打开页面,自动点击播放 - 监听网络请求,提取
.m3u8 - 用
ffmpeg下载并转成MP4(H.264编码) - 压缩到适当大小
- 自动告诉你在PPT里怎么插入
代码不放了(太长),但核心就是上面那几段拼起来,你在自己项目里照着写,半小时就能搞定。
对了,遇到一个bug想跟大家说:百度视频的页面里藏着很多data-src属性的图片,不是视频,别搞混了,我一开始正则匹配就把图片链接当视频抓了,还纳闷为什么播放不了。
现阶段我用下来最顺手的组合
- 下载视频:Go写的小爬虫(上面那套)
- 转格式+压缩:ffmpeg命令行(记得加
-movflags +faststart参数,方便PPT里拖动进度条) - 插入PPT:本地文件,不要用在线链接,别信PPT365的“在线视频”功能
你要是流量不多,也可以把视频传到你的私有服务器或者对象存储(比如阿里云OSS),然后把MP4链接用PPT365的“来自在线视频”选项插入——这个能通,因为PPT365支持直接解析MP4直链。别用百度网盘的分享链接,那种页面不支持。
不完美的地方,我承认
说实话,这个方法不是100%灵,百度一直在改版,今天能抓的URL,下周可能就失效了,你要是经常需要抓,建议自己维护一个Cookie池(登录状态下权限高很多)。
还有,高清视频(1080P)抓下来很慢,还要处理防盗链,我有个同事抓了个4K的视频,跑了40分钟才下完,后来发现PPT根本播不动4K,纯属白费劲,PPT里1080P就顶天了,720P更合适(文件小,播放顺滑)。
有时候半夜接到领导电话说“视频插不进去”,我就远程跑一下我的Go爬虫,一分钟出结果,丢给他一个MP4文件,这事儿就算解决了,挺好。
本文来自作者[kyadmin]投稿,不代表be365立场,如若转载,请注明出处:http://www.hljbesthome.com/tiyu/2601.html
评论列表(4条)
我是be365的签约作者“kyadmin”!
希望本篇文章《PPT365里抓百度视频?这活儿我干过,踩坑实录+可行方案(Go语言版)》能对你有所帮助!
本站[be365]内容主要涵盖:be365,be365网站,be365网址,ball365体育,Be365排名
本文概览:这事儿没那么简单兄弟们,我懂你们,做PPT做到半夜,想在某一页里插个百度视频,结果PPT365自带的“在线视频”功能要么搜不到,要么...