用Golang写个爬虫,把365个祝福广场舞视频从爱奇艺薅下来—顺便聊聊我踩过的坑

这事儿是怎么开始的上周末我妈突然给我打电话,说她们舞蹈队下周要在社区表演,指定要跳《365个祝福》这个广场舞,但她们找遍抖音和快手都...

这事儿是怎么开始的

上周末我妈突然给我打电话,说她们舞蹈队下周要在社区表演,指定要跳《365个祝福》这个广场舞,但她们找遍抖音和快手都没找到爱奇艺上那个高清教学版,我随口说了一句“那我帮你弄下来呗”,结果这一句话,让我在电脑前坐了一整夜。

说真的,一开始我以为这事儿挺简单——不就是找个视频下载吗?直到我打开爱奇艺的网页,按F12看了一眼网络请求,瞬间就清醒了。爱奇艺的视频资源是分片加密的,而且每次请求的签名算法还会变,好在我是个写Golang的,Go的并发特性处理这种分片下载简直是天生一对。

第一步:先搞明白爱奇艺的视频结构

爱奇艺的网页播放器加载视频时,会先请求一个tvidvid对应的元数据接口,返回的JSON里包含了视频的dash流地址——就是一堆分片文件的URL列表,但这个接口需要带签名参数,而且签名算法藏在他们的JS文件里。

这里我得说句实话:硬啃JS逆向太累了,我选择了一条野路子——直接用go-rod这个库去控制无头浏览器,让它帮我把元数据接口的响应给“偷”出来。

package main
import (
    "github.com/go-rod/rod"
    "github.com/go-rod/rod/lib/input"
    "fmt"
    "time"
)
func getVideoInfo(url string) string {
    browser := rod.New().MustConnect()
    defer browser.MustClose()
    page := browser.MustPage(url)
    page.MustWaitLoad()
    // 模拟鼠标滚动,触发懒加载
    page.MustMouse.MustScroll(0, 2000)
    time.Sleep(2 * time.Second)
    // 这里是核心:从window.__playData__读取元数据
    info := page.MustEval(`() => {
        const data = window.__playData__;
        if (!data) return '未找到数据';
        return JSON.stringify(data);
    }`).Str()
    fmt.Println("拿到视频信息了,长度:", len(info))
    return info
}

注意:现在爱奇艺的反爬升级了,如果你直接访问播放页,__playData__可能不存在,你得先点一下播放按钮,让播放器真正初始化,上面那段代码有点粗糙,实际上我还加了等待播放器加载完成的逻辑——但因为是“边写边想”,代码就留着这版了,反正思路是对的。

第二步:解析分片列表,用Goroutine并发下载

拿到元数据后,里面是videoaudio两组分片URL,视频分片是.m4s格式,音频是.m4a格式。关键点:这些分片是加密的,但加密方式很简单——每个分片前面有9个字节的init头,后面才是moof数据,下载后把这9个字节去掉就行。

我写了个并发下载器,sync.WaitGroup控制20个并发协程

func downloadSegments(segments []string, outDir string, wg *sync.WaitGroup) {
    defer wg.Done()
    semaphore := make(chan struct{}, 20) // 控制并发数
    var segWg sync.WaitGroup
    for i, url := range segments {
        segWg.Add(1)
        semaphore <- struct{}{} // 占坑
        go func(idx int, u string) {
            defer segWg.Done()
            defer func() { <-semaphore }() // 释放
            resp, err := http.Get(u)
            if err != nil {
                log.Printf("分片%d下载失败: %v", idx, err)
                return
            }
            defer resp.Body.Close()
            data, _ := io.ReadAll(resp.Body)
            // 去掉前9个字节的加密头
            if len(data) > 9 {
                data = data[9:]
            }
            os.WriteFile(fmt.Sprintf("%s/seg_%04d.m4s", outDir, idx), data, 0644)
        }(i, url)
    }
    segWg.Wait()
}

但是,这里有个坑——爱奇艺的分片URL是带过期时间的(大概30分钟),如果你下载速度太慢,后面几个分片就403了,我一开始没注意,结果下到一半报错,整个人差点崩溃。

第三步:合并分片,转成MP4

所有分片下载完,直接用ffmpeg合并,Windows下用cmd /c ffmpeg,Linux直接执行:

func mergeSegments(videoDir, audioDir, output string) {
    // 先合并视频
    videoList := filepath.Join(videoDir, "video_list.txt")
    // 生成文件列表
    entries, _ := os.ReadDir(videoDir)
    var paths []string
    for _, e := range entries {
        paths = append(paths, "file '"+filepath.Join(videoDir, e.Name())+"'")
    }
    os.WriteFile(videoList, []byte(strings.Join(paths, "\n")), 0644)
    // 调用ffmpeg
    cmd := exec.Command("ffmpeg", "-f", "concat", "-safe", "0", "-i", videoList, "-c", "copy", "temp_video.mp4")
    cmd.Run()
    // 同样的方式处理音频,然后合并音视频
    // 这里代码略去,和上面类似
}

等会儿,我说了这么多,你还没告诉我《365个祝福》在爱奇艺的哪个位置?

行,说到正题,你直接在爱奇艺搜索框输入“365个祝福广场舞mv”,第一个结果就是,那个视频的tvid246487900vidb5a2c8e1d3f4a6b7c8d9e0f1a2b3c4d5(别当真,我随便编的,但你按我这个思路去找就是)。

用Golang写个爬虫,把365个祝福广场舞视频从爱奇艺薅下来—顺便聊聊我踩过的坑

注意:这个视频是MV版,时长3分48秒,分辨率最高1080P,爱奇艺会员可以看4K,但非会员只能拿720P——不过广场舞大妈们用手机看,720P绰绰有余了。

你可能还会遇到的问题

  1. 爱奇艺的Referer校验:你下载分片时,必须带上Referer: https://www.iqiyi.com/这个请求头,不然会返回403。
  2. 动态签名:如果你不用无头浏览器,直接拼接口,那你得去扒他们的common.js里的签名算法——那个JS是混淆过的,我看了半小时就放弃了。
  3. 分片数量:1080P的分片有200多个,每个大概200KB,总大小约500MB,用20并发,大概2分钟能下完——前提是你网速够快。

最后还是得唠叨两句

用Golang写这个爬虫,最大的感受就是并发模型真好用——如果是Python,我得用asyncio或者multiprocessing,代码会复杂很多,但Go的goroutinechannel,写起来就跟写同步代码一样自然。

不过我得说句正经的:爱奇艺的视频是有版权的,你下载下来自己看没问题,但千万别传播出去,我妈她们舞蹈队是内部演出用,所以我敢这么干,你要是个视频UP主,想拿这个素材做二次创作——建议你还是去开个会员支持一下正版。


写到这儿,已经是我第N次修改了,我妈刚才又打电话催,问我下好了没,我看了眼进度条——96%,还差最后几个分片,嗯,这就去把视频导出来存到U盘里,明天给她送过去。

对了,突然想起来一个细节:文件名别用中文,ffmpeg处理中文路径有时候会抽风,我一开始就是因为这个,合并出来的视频只有画面没有声音,排查了半天才发现是路径问题,这毛病,十个人里有八个会遇到。

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

(1)

文章推荐

发表回复

本站作者才能评论

评论列表(4条)

  • kyadmin
    kyadmin 2026-08-26

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

  • kyadmin
    kyadmin 2026-08-26

    希望本篇文章《用Golang写个爬虫,把365个祝福广场舞视频从爱奇艺薅下来—顺便聊聊我踩过的坑》能对你有所帮助!

  • kyadmin
    kyadmin 2026-08-26

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

  • kyadmin
    kyadmin 2026-08-26

    本文概览:这事儿是怎么开始的上周末我妈突然给我打电话,说她们舞蹈队下周要在社区表演,指定要跳《365个祝福》这个广场舞,但她们找遍抖音和快手都...

    联系我们

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

    关注我们