当前位置:首页 > 能源 > 正文

在一起365天视频下载,用Go语言写了个小工具,把我们的回忆存成了代码

  • 能源
  • 2026-08-17 18:04:11
  • 74
摘要: 昨天半夜,我盯着手机里那个“在一起365天”的纪念日视频,眼眶有点热,视频是女朋友偷偷剪的,从第一次约会到搬家,从吵架到和好,3...

昨天半夜,我盯着手机里那个“在一起365天”的纪念日视频,眼眶有点热,视频是女朋友偷偷剪的,从第一次约会到搬家,从吵架到和好,365个日夜浓缩成七分多钟,可问题是——这视频在微信聊天记录里,画质被压缩成渣,而且过几天可能就被清理了,我立刻想到,得把它下载下来,存到本地NAS里,最好还能按时间戳整理成文件夹。

但现实是,手机里那个“下载”按钮永远转圈,电脑网页版微信又登录不了,我干脆打开电脑,用Go语言写了个小脚本,半小时搞定了这件事,今天不聊浪漫,聊聊技术——怎么用Go写一个靠谱的视频下载器,顺便说说这过程中的坑。

为什么选Go而不是Python?

说实话,Python写爬虫下载视频更常见,requests+BeautifulSoup一把梭,但我的需求有点特殊:视频是从微信下载的,链接是https://weixin.qq.com/xxx?t=xxxx这种临时URL,而且需要模拟登录状态,还要处理重定向、断点续传,Go的net/http标准库够用,而且编译出来是个单文件,扔到服务器上就能跑,不用装环境——这对我这种经常在树莓派上折腾的人太友好了。

Go的并发模型处理多段下载简直是天作之合,一个视频几十MB,拆成4个goroutine同时拉,速度直接翻倍,Python的GIL在这事儿上会卡脖子,Go没有这个烦恼。

核心代码:三个步骤搞定下载

我写了个不到200行的工具,分三步走,先贴关键代码,再解释思路。

第一步:从微信URL里提取真实下载地址

微信的视频链接通常是https://weixin.qq.com/xxx,但会302重定向到https://v.qq.com/xxx.mp4这种真实地址,你需要:

resp, err := http.Get(originalURL)
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()
// 关键:检查重定向
if resp.StatusCode == 302 || resp.StatusCode == 301 {
    realURL := resp.Header.Get("Location")
    fmt.Println("真实地址:", realURL)
}

但微信的坑在于——有时候重定向不止一次,我遇到过连续5次302,最后一次才拿到.mp4后缀,所以用http.ClientCheckRedirect字段循环处理更稳妥。

第二步:并发下载视频分片

拿到真实URL后,先发个HEAD请求,读Content-Length拿总大小,然后切成4个区间,每个goroutine下自己的部分:

var wg sync.WaitGroup
chunkSize := totalSize / 4
for i := 0; i < 4; i++ {
    wg.Add(1)
    go func(start, end int64) {
        defer wg.Done()
        req, _ := http.NewRequest("GET", realURL, nil)
        req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", start, end))
        // ... 下载并写入临时文件
    }(int64(i)*chunkSize, int64(i+1)*chunkSize-1)
}
wg.Wait()

这里有个细节:微信服务器可能不支持Range头,返回200而不是206,所以必须做校验,如果响应头没有Content-Range,就直接降级成单线程下载,别硬搞并发。

第三步:合并分片并校验完整性

下载完4个.part文件后,用os.OpenFile依次写入目标文件,别忘了解析Content-MD5做校验——微信偶尔会丢包,合并完发现视频花屏就尴尬了。

附:我踩过的三个坑(保命经验)

  1. User-Agent必须伪装,微信会把非微信浏览器的UA直接拒掉,返回403,我用Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X) AppleWebKit/605.1.15,一次就过。
  2. Cookie有时效性,微信链接里的t参数有效期大概2小时,如果你下载失败,重新从聊天记录里复制链接,别自己拼参数。
  3. 文件名别用中文,Windows下中文文件名容易出编码问题,我统一转成拼音+日期格式,比如beauty_2025_0401.mp4

优化:把脚本变成命令行工具

光能跑还不够,我加了三个flag,让女朋友也能用:

参数 作用 示例
-url 视频链接 -url "https://weixin.qq.com/xxx"
-out 输出路径 -out "D:/回忆/周年纪念.mp4"
-resume 断点续传 -resume=true

flag包解析参数,然后go build -o vdown编译成单文件,现在她只要双击运行一个run.bat就能下载,完全不用命令行。

写在最后:代码和感情一样,需要慢慢调

今天早晨起来,看到NAS里多了个365天.mp4,1.2GB,4K原画,我打开电脑,看了最后十秒——镜头里她笑得像个傻子,我也一样,这个工具可能只对两个人有用,但写它的过程让我想起刚在一起时,她教我用吉他弹《小星星》的情景:一开始总是跑调,但坚持调弦,总能找到对的音

如果你也需要下载某个平台上的视频,别急着找现成的“万能下载器”——那些工具要么收费,要么捆绑广告,花半小时写个Go脚本,既学了新技能,又能保证数据安全,毕竟,自己的回忆,还是用自己写的代码守着最放心

在一起365天视频下载,用Go语言写了个小工具,把我们的回忆存成了代码