用Go语言写个脚本,把365视频教程从百度网盘批量搬回家

百度网盘里那堆吃灰的教程我赌你手机里肯定躺着几个“先存了再说”的百度网盘链接,尤其是那种标着“365视频教程”的资源包——从Pyth...

百度网盘里那堆吃灰的教程

我赌你手机里肯定躺着几个“先存了再说”的百度网盘链接,尤其是那种标着“365视频教程”的资源包——从Python入门到AI进阶,从Excel函数到视频剪辑,一年365天恨不得天天给你安排得明明白白,可问题是,网盘限速那叫一个酸爽,想下载个10G的压缩包,能给你拖到天荒地老,更烦的是,有时候急用某个章节,还得翻半天目录,我这人吧,恰好手头有个Go语言的活儿,灵机一动——能不能写个小工具,把百度网盘里的365视频教程按目录结构批量同步到本地? 说干就干,这篇文章就是记录我怎么用Go语言一步步搞定的,顺便把核心代码思路掰开揉碎了讲给你听。

用Go语言写个脚本,把365视频教程从百度网盘批量搬回家

第一步:先搞懂百度网盘的API到底给不给面子

百度网盘开放平台其实提供了官方API,主要两个接口跟下载有关:

  • /rest/2.0/xpan/multimedia:用于获取文件列表和元数据
  • /rest/2.0/xpan/file:用于下载文件(需要申请netdisk权限)

你得先去百度开发者平台注册个应用,拿到access_token,这个token说白了就是你的“钥匙”,每次请求都得带上,关键点来了——百度网盘API有个限制:单次请求最多返回100个文件/目录,要是你的365视频教程文件夹里塞了上千个文件,你得写个循环翻页。

我的做法是先建一个FileInfo结构体,把文件路径、大小、md5这些存起来:

type FileInfo struct {
    Path string `json:"path"`
    Size int64  `json:"size"`
    Md5  string `json:"md5"`
    Isdir int   `json:"isdir"`
    ServerMtime int64 `json:"server_mtime"`
}

然后调API拿目录列表,用startlimit参数翻页。注意,百度返回的path是完整路径(比如/apps/365视频教程/第01章-基础篇/第1节-环境搭建.mp4),你本地也得建同样的目录结构,不然文件全堆一个文件夹里就乱套了。

第二步:用Go写个“伪并发”下载器

百度网盘下载有个坑:同一个token并发太高会被封,我试过开10个goroutine同时下,结果下到一半突然403,一查是触发了风控,所以后来我机智地用了“信号量模式”——先开个固定大小的worker池,比如5个,每个worker负责下载一个文件,任务从channel里取。

sem := make(chan struct{}, 5) // 最多5个并发
for _, f := range fileList {
    sem <- struct{}{} // 占坑
    go func(f FileInfo) {
        defer func() { <-sem }() // 释放坑
        downloadFile(f)
    }(f)
}

下载逻辑本身用的是net/httpGet,但有两个细节要注意:

  1. 必须带User-Agent——百度会检测UA,没带会被拒
  2. 支持断点续传——用Range头,万一中途断了,下次续传而不是重头下。
req, _ := http.NewRequest("GET", downloadURL, nil)
req.Header.Set("Range", fmt.Sprintf("bytes=%d-", offset))
resp, err := client.Do(req)

这里有个小坑:百度返回的下载链接是临时有效的(大概30分钟),所以你得先获取到一个有效的下载链接,再立即开始下载,要是文件太大超过了时效,就得重新拿链接,我的解决办法是:拿到链接后,先用一个goroutine去HEAD请求探活,如果过期再重新获取。

第三步:本地文件校验——别下了一堆损坏的MP4

下载完不等于完事儿,还得校验,你猜怎么着?百度网盘API里给的md5其实有点坑——那个md5是文件完整内容的md5,但下载时可能会因为网络原因丢包,所以我下了个狠招:每下载完一个文件,用Go的crypto/md5算一遍本地文件的哈希,跟API返回的比对,不一致就删掉重新下载。

func verifyFile(path string, expectedMD5 string) bool {
    f, err := os.Open(path)
    if err != nil { return false }
    defer f.Close()
    h := md5.New()
    io.Copy(h, f)
    actualMD5 := hex.EncodeToString(h.Sum(nil))
    return actualMD5 == expectedMD5
}

不过说实话,对于那种4K超清视频(动辄几个G),算一次md5也得几十秒,所以我又加了个捷径——优先比较文件大小,大小对不上肯定有问题,大小一致再算md5,这样能省不少时间。

第四步:处理“重名文件”和“非法字符”

Windows和Linux的目录命名规则不一样,你那365教程里要是有一集叫第10讲-如何打出「|」符号.mp4,在Windows下直接创建文件会报错,因为是非法字符,所以我写了个sanitize函数:

func sanitize(filename string) string {
    forbidden := []string{`\`, `/`, `:`, `*`, `?`, `"`, `<`, `>`, `|`}
    for _, ch := range forbidden {
        filename = strings.ReplaceAll(filename, ch, "_")
    }
    return strings.TrimSpace(filename)
}

如果同一目录下有重名文件(比如教程更新过,存了两个版本),百度网盘API会返回两个相同path的对象,但你本地没法建两个同名文件,我的策略是:检测到重名,就在第二个后面加_1_2这样的后缀。

第五步:把日志写明白,不然断点都不知道在哪儿

下载最怕中途崩了,然后忘了下到哪儿了,我加了个简单的日志记录,每完成一个文件,就往progress.log里写一行:

[2025-03-18 14:22:31] DONE /apps/365视频教程/第01章/第1节.mp4 | 234MB | md5: 3f9a...
[2025-03-18 14:23:45] SKIP /apps/365视频教程/第01章/第2节.mp4 (已存在)

然后启动时先读这个log,把已经存在的文件跳过,实现“断点续传”,别小看这个,我第一版没做,结果下到一半网断了,恢复后从头开始,那叫一个崩溃。

第六步:终于跑起来了——但还有几个彩蛋问题

你以为这就完了?现实总是比理想骨感,我实际跑的时候碰见几个贼有意思的情况:

  1. 百度网盘API偶尔返回-9错误码——人家官方文档说是“操作过于频繁”,得等几秒再重试,我加了指数退避重试,最多重试5次。

  2. 某些视频文件被百度标记为“违规”——即使你之前能在线播放,API也可能下载不下来,返回-11,这种情况只能跳过并在日志里记下来。

  3. 大文件下载的时候,临时链接过期——我上面提过,解决办法是拿链接后,每次写文件时先检查下当前时间跟链接到期时间比较,如果快到期了,就中断重新获取链接再续传。

你想自己搞一个不?

整个脚本大概300多行Go代码,核心依赖只有标准库net/httpospath/filepath这些,我目前这个版本已经帮我把网盘里80多G的365视频教程全部同步到本地固态硬盘了,之后直接接Plex或者本地播放器看,爽歪歪,哦对了,还有个小建议:下载的时候最好把GOMAXPROCS设置成你的CPU核心数减一,不然全速跑的时候你的机器会卡成PPT,别问我怎么知道的。

如果你也想搞一个,建议先去百度开发者平台申请一个应用,拿到token,然后从列目录开始一步步调通,遇到-9别慌,退避重试就行,希望这篇文章能省你半天时间,祝你也能把网盘里的“吃灰教程”变成实打实能看的本地视频。

本文来自作者[kyadmin]投稿,不代表be365立场,如若转载,请注明出处:http://hljbesthome.com/lvyou/2259.html

(16)

文章推荐

发表回复

本站作者才能评论

评论列表(4条)

  • kyadmin
    kyadmin 2026-08-14

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

  • kyadmin
    kyadmin 2026-08-14

    希望本篇文章《用Go语言写个脚本,把365视频教程从百度网盘批量搬回家》能对你有所帮助!

  • kyadmin
    kyadmin 2026-08-14

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

  • kyadmin
    kyadmin 2026-08-14

    本文概览:百度网盘里那堆吃灰的教程我赌你手机里肯定躺着几个“先存了再说”的百度网盘链接,尤其是那种标着“365视频教程”的资源包——从Pyth...

    联系我们

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

    关注我们