当前位置:首页 > 单站 > 正文

用Golang扒拉365dni西瓜视频中文字幕?这事儿我试过

  • 单站
  • 2026-06-28 14:50:02
  • 831
摘要: 这事儿吧,得从一个小需求说起,我媳妇追《365dni》追得紧,但西瓜视频上那字幕翻译吧……有时候真让人挠头,有的地方漏译,有的地...

这事儿吧,得从一个小需求说起,我媳妇追《365dni》追得紧,但西瓜视频上那字幕翻译吧……有时候真让人挠头,有的地方漏译,有的地方干脆对不上口型,我寻思着,能不能用Golang自己把那中文字幕给扒拉下来,然后重新整理一遍?

听起来像技术宅的自嗨?还真不是,这事儿做成了,以后追剧自己调字幕、加注释,都方便,咱们就用费曼法,把这过程掰开揉碎了讲。

第一步:搞清楚“扒字幕”到底扒的是什么

先说句得罪人的实话:视频网站的字幕,一般不是视频里“烧”进去的图片,它们大多藏在网络请求里,是一个独立的文本文件,在西瓜视频上,它通常是 JSON格式 或者 SRT格式

想象一下:每一句台词,都带着一个时间戳和一个字符串,Golang要做的,就是发起网络请求拿到这些数据,再解析出来,就这么简单。

你打开浏览器开发者工具(F12),找到Network选项卡,过滤一下“subtitle”或者“vtt”关键词,如果看到类似这样的请求:

https://.../subtitle/12345.vtt

恭喜你,找到目标了。

第二步:用Golang“对话”服务器

这一步,我们得写几行代码,让Golang帮我们向西瓜视频的服务器要那份字幕文件。

关键是用标准库net/http,别想复杂了,就是模拟浏览器发个GET请求,但有个小坑:服务器可能会检测请求头,所以最好带上User-Agent,假装自己是主流浏览器。

package main
import (
    "fmt"
    "io"
    "net/http"
    "os"
)
func main() {
    // 这里的URL是你从浏览器拿到的那条字幕地址
    url := "https://example.com/365dni/subtitle.zh.vtt"
    req, _ := http.NewRequest("GET", url, nil)
    req.Header.Set("User-Agent", "Mozilla/5.0 ...")
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        fmt.Println("请求失败:", err)
        return
    }
    defer resp.Body.Close()
    body, _ := io.ReadAll(resp.Body)
    // 存到本地文件
    os.WriteFile("365dni_subtitle.vtt", body, 0644)
    fmt.Println("字幕下载成功,内容如下:")
    fmt.Println(string(body[:200])) // 先看前200个字符
}

这么跑一下,你就得到了一份原始的字幕文件,但问题来了:VTT格式的文本,往往夹着一堆时间轴和序号,读起来眼睛疼。

第三步:把VTT格式“翻译”成咱们能看的

假设下载下来的文件长这样:

WEBVTT
1
00:00:01.500 --> 00:00:04.000
劳拉,你准备好了吗?
2
00:00:05.000 --> 00:00:08.500
这将会是非常特别的一天。

咱们只想要时间戳字幕文本,用Golang解析它,最笨也最靠谱的方法是按行读,判断哪行是数字、哪行是时间、哪行是文本。

我习惯用bufio.Scanner逐行扫描,遇到数字行就跳过去,遇到时间行存下来,遇到文本行就和时间拼一起输出。

func parseVTT(filename string) {
    file, _ := os.Open(filename)
    scanner := bufio.NewScanner(file)
    var currentTime string
    for scanner.Scan() {
        line := scanner.Text()
        if strings.Contains(line, "-->") {
            currentTime = strings.Split(line, " --> ")[0]
        } else if line != "" && !strings.HasPrefix(line, "WEBVTT") && !isDigit(line) {
            fmt.Printf("[%s] %s\n", currentTime, line)
        }
    }
}

这么一搞,输出就清爽多了,再导入Excel或者随便一个文本编辑器,就是一份干净的双语字幕素材。

第四步:解决实际中的“脏数据”问题

真干起来的时候,你会发现西瓜视频的字幕可能藏在混淆后的接口里,比如请求里有token参数,或者返回的数据是Base64编码的。

这时候别慌,拿Golang的encoding/base64包一把梭:

import "encoding/base64"
decoded, _ := base64.StdEncoding.DecodeString(encodedStr)
fmt.Println(string(decoded))

如果遇到中文乱码,大概率是编码问题,试试把响应体转成 UTF-8

import "golang.org/x/text/encoding/chinese"
decoder := chinese.GBK.NewDecoder()
utf8Bytes, _ := decoder.Bytes(body)

这一套组合拳下来,365dni西瓜视频中文字幕数据基本就到手了。

我踩过的坑(你们别踩了)

坑点 原因 解决办法
请求被拒 缺少Referer头 加上req.Header.Set("Referer", "https://www.ixigua.com/")
字幕时间错位 解析时忽略了时间格式差异 统一用时间字符串比较,或者转成毫秒再操作
中文变成??? 解包后没转Unicode json.Unmarshal之前先检查响应编码

还有一次,我发现西瓜视频的字幕接口参数里带了个aid,不同视频不一样,怎么办?硬着头皮用Go的正则表达式从页面源码里抠出来,虽然笨,但管用。

结尾想啥写啥

说到底,用Golang搞字幕这事儿,没啥高深的,就是找接口 → 发请求 → 解析数据三步,GitHub上其实也有现成的库,比如golang.org/x/net/html能帮你解析页面,github.com/PuerkitoBio/goquery能像jQuery一样操作DOM,但我个人觉得,自己手写一遍,理解才深。

倒是后来我发现,西瓜视频有些老剧的字幕接口早换了,得用WebSocket去拿实时流,那又是另一个故事了,反正追剧追到这份儿上,也算是真爱了,你们要是真去试,碰到报错也别慌——把错误信息扔搜索引擎,八成能找到解决方案,毕竟,折腾的过程本身就有意思。