用Golang写个工具,把365dni、百度网盘和西瓜视频串起来

想在西瓜视频上看个东西,结果发现资源藏在百度网盘里,还得下载下来才能看?更别提有时候链接就是“365dni”这种命名方式,文件夹里层层叠...

想在西瓜视频上看个东西,结果发现资源藏在百度网盘里,还得下载下来才能看?更别提有时候链接就是“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”,系统可能认成别的视频。

用Golang写个工具,把365dni、百度网盘和西瓜视频串起来

我写了个格式转换函数,把百度网盘拿到的原始文件名(比如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

(10)

文章推荐

发表回复

本站作者才能评论

评论列表(4条)

  • kyadmin
    kyadmin 2026-07-01

    我是be365的签约作者“kyadmin”!

  • kyadmin
    kyadmin 2026-07-01

    希望本篇文章《用Golang写个工具,把365dni、百度网盘和西瓜视频串起来》能对你有所帮助!

  • kyadmin
    kyadmin 2026-07-01

    本站[be365]内容主要涵盖:be365,be365网站,be365网址,ball365体育,Be365排名

  • kyadmin
    kyadmin 2026-07-01

    本文概览:想在西瓜视频上看个东西,结果发现资源藏在百度网盘里,还得下载下来才能看?更别提有时候链接就是“365dni”这种命名方式,文件夹里层层叠...

    联系我们

    工作时间:周一至周五,9:30-18:30,节假日休息

    关注我们