用Golang扒拉365dni西瓜视频中文字幕?这事儿我试过
- 单站
- 2026-06-28 14:50:02
- 831
这事儿吧,得从一个小需求说起,我媳妇追《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去拿实时流,那又是另一个故事了,反正追剧追到这份儿上,也算是真爱了,你们要是真去试,碰到报错也别慌——把错误信息扔搜索引擎,八成能找到解决方案,毕竟,折腾的过程本身就有意思。