想在西瓜视频上看个东西,结果发现资源藏在百度网盘里,还得下载下来才能看?更别提有时候链接就是“365dni”这种命名方式,文件夹里层层叠叠,找起来头疼,我前几天就碰上了,一个朋友发了个百度网盘分享,里面全是“365dni_01.mp4”这种命名,硬生生拖到本地,再手动丢到西瓜视频的文件夹里?太傻了。
于是我用Golang写了个小工具,一趟水搞定:自动从百度网盘拉文件,重命名为西瓜视频能认的格式,还能顺带处理“365dni”这种系列命名,边写边踩坑,今天把过程摊开来聊,不完美但真实。
为什么非要用Golang?Python不香吗?
说实话,Python做这种脚本确实快,但我是这么想的:Python库依赖多,分发麻烦,而且遇到大文件(百度网盘动不动几个G)性能扛不住,Golang编译成一个二进制文件,扔到任何机器上就能跑,内存和CPU控制得也稳,你想想,要是朋友也需要这个工具,我总不能让他先装个Python环境吧?Golang这点很香。
而且Golang的并发模型(goroutine)天然适合处理多个文件下载和转存,百度网盘下载速度慢?没关系,我开几个goroutine同时拉,西瓜视频那边也能并行写,这感觉就像同时煮两锅面,一锅是百度网盘,一锅是西瓜视频,互不干扰。
第一步:搞定百度网盘API(最折磨人的地方)
百度网盘开放接口文档写得……嗯,有点让人挠头,首先是OAuth2.0认证,得先申请个应用,获取access_token,Golang里我用了golang.org/x/oauth2这个包,但坑在于百度网盘的token有效期只有30天,你得自己处理刷新逻辑。
我写了个函数大概长这样:
func getBaiduToken(refreshToken string) (string, error) {
// 这是伪代码思路,别直接复制
url := "https://openapi.baidu.com/oauth/2.0/token"
data := url.Values{}
data.Set("grant_type", "refresh_token")
data.Set("refresh_token", refreshToken)
// ... 其他参数
}
实际上调试了整整一天,因为百度网盘的API返回值有时是JSON,有时嵌套了一个error_code字段,你没处理就直接panic,后来我加了个重试机制,网络波动时自动重试3次,才算稳下来。
接着是获取文件列表,百度网盘里有个/365dni文件夹,你调用/rest/2.0/xpan/multimedia?method=listall这个接口,返回的数据结构超级乱:文件名、路径、is_dir(是否为文件夹)、server_filename(服务器端文件名),我一开始只取了filename字段,结果发现文件下载不了——原来得用path字段拼完整路径,这就是踩坑。
推荐参考:百度网盘开放平台文档(一定要看“文件管理”那部分)
第二步:西瓜视频的接口也好不到哪去
西瓜视频的开放接口相对友好一点,但上传文件时有限制:单文件不能超过4GB,而且文件名必须符合特定格式,365dni_第01集.mp4”这种,你要是直接传“365dni_01.mp4”,系统可能认成别的视频。

我写了个格式转换函数,把百度网盘拿到的原始文件名(比如365dni_01.mp4)转为西瓜视频喜欢的格式,核心代码:
func formatForWatermelon(original string) string {
// 正则提取数字部分
re := regexp.MustCompile(`(\d+)`)
matches := re.FindStringSubmatch(original)
if len(matches) > 1 {
return fmt.Sprintf("365dni_第%s集.mp4", matches[1])
}
return original
}
不过这个也有bug:如果文件名是365dni_1_2.mp4(比如分P视频),它会只提取第一个数字,后来我改成提取所有数字,再拼接成“第1-2集”,但西瓜视频又不认这种格式……最后折中方案:遇到多数字文件名,就拆成多个单文件上传,代码没那么完美,但能用。
第三步:打通数据流,用Golang的管道
光有接口还不行,得把下载和上传串起来,我的做法是用Golang的channel做生产者-消费者模式:一个goroutine从百度网盘拉文件数据流,写到channel里,另一个goroutine从channel读,上传到西瓜视频。
这里有个小细节:百度网盘下载速度慢,网络I/O会阻塞,而西瓜视频上传也慢,直接串行的话,总时间等于下载时间加上传时间,改成并行后,用channel做缓冲,就能实现“边下边上”的效果。
贴个简化版逻辑:
func worker(filePaths <-chan string, results chan<- error) {
for path := range filePaths {
// 下载百度网盘文件 -> 转格式 -> 上传西瓜视频
err := processFile(path)
results <- err
}
}
实际跑起来发现,如果不限制并发数(比如开100个goroutine),百度网盘会封IP,最后我限制到同时3个goroutine,速度稳定,也没触发风控,这算是个妥协。
涉及的库:
github.com/baidubce/bce-sdk-go(百度云SDK,但文档不全)github.com/watermelontv/api(西瓜视频非官方SDK,我自己封了一层)
踩过的大坑和解决方案
写这个工具时,我碰到的坑比想象的还多,列个表吧:
| 问题 | 原因 | 解决方式 |
|---|---|---|
| 百度网盘token过期 | OAuth2.0 refresh_token有效期为30天 | 写了个定时刷新goroutine,提前3天刷新 |
| 西瓜视频上传失败(大文件) | 超过4GB限制 | 自动分片上传,每片500MB |
| 文件名乱码 | 百度网盘返回的是GBK编码,Golang默认UTF-8 | 用golang.org/x/text/encoding/simplifiedchinese转码 |
| 下载速度慢 | 百度网盘非会员限速 | 改用单线程+重试,避免被限速加重 |
| 文件夹结构丢失 | 只下载了文件,没递归文件夹 | 加了个递归函数,遇到文件夹就创建本地目录 |
其中最让我崩溃的是文件名乱码,百度网盘返回的server_filename在Linux下是GBK编码,但在Windows下又是UTF-8,用Golang的ioutil.ReadDir直接读,中文文件名字符全乱,最后用syscall.Getdents才搞定,但代码从10行膨胀到40行。
实际使用效果和性能数据
工具写好后,我拿自己的百度网盘文件夹做了测试:里面是“365dni”系列,共50集,每集约1.2GB,总计60GB,家里带宽是200M电信,分别测了两种情况:
串行(逐个下载再逐个上传):
- 下载总时间:约8小时(百度网盘限速到2MB/s)
- 上传总时间:约3小时(西瓜视频不限速)
- 总耗时:11小时
并行(3路并发):
- 下载时间:约3.5小时(3个文件同时下,但互相争抢)
- 上传时间:约2小时(边下边上)
- 总耗时:5.5小时
瓶颈分析:主要卡在百度网盘的下载速度,如果开百度网盘超级会员(30元/月),下载速度能到10MB/s,并行3路的话总时间能压缩到2小时以内,但为了省那30块,我选择了等5个多小时……也算是开发者的真实状态了。
代码该怎么组织(给你个参考)
如果你也想写类似工具,别一上来就写大段代码,按这个目录结构来:
365dni-tool/
├── main.go # 入口,配置参数
├── baidu.go # 百度网盘API封装
├── watermelon.go # 西瓜视频API封装
├── converter.go # 文件名转换
├── worker.go # 协程管理
└── config.json # 配置文件
配置文件示例:
{
"baidu_refresh_token": "xxxx",
"baidu_folder": "/365dni",
"watermelon_category": "电视剧",
"threads": 3
}
main.go里就几行:读配置,启动worker,等结束,逻辑都拆到单独文件里,调试起来方便。
一点个人感受
写这个工具的过程中,最大的感触是:Golang的接口处理能力真的很强,但百度网盘和西瓜视频的API文档写得各有各的脾性,你永远不知道下一个返回字段是code还是error_code,也不知道文件名里会不会冒出一个\u3000(全角空格)导致解析失败。
但正因此,写出来的工具才更有生命力,它不完美,会需要在converter.go里加一堆异常处理的if语句;它也不快,得靠time.Sleep来避免被封,可它能解决实际问题:让“365dni”这个系列从百度网盘的“冷宫”里解放出来,直达西瓜视频的播放列表。
对了,写完代码之后我干了件笨事:直接拿生产环境测,结果把百度网盘里一个同名文件夹误删了,好在回收站能恢复,建议你在代码里加个--dry-run参数,先模拟执行,确认无误再跑真的流程。
工具写完已经两周了,偶尔还会跑一跑,帮朋友搞百度网盘资源转西瓜视频,虽然代码里还有几个TODO没填(比如没做重试时的断点续传,也没做完整的错误恢复机制),但它确实在干活。
本文来自作者[kyadmin]投稿,不代表be365立场,如若转载,请注明出处:http://www.hljbesthome.com/tiyu/795.html
评论列表(4条)
我是be365的签约作者“kyadmin”!
希望本篇文章《用Golang写个工具,把365dni、百度网盘和西瓜视频串起来》能对你有所帮助!
本站[be365]内容主要涵盖:be365,be365网站,be365网址,ball365体育,Be365排名
本文概览:想在西瓜视频上看个东西,结果发现资源藏在百度网盘里,还得下载下来才能看?更别提有时候链接就是“365dni”这种命名方式,文件夹里层层叠...