用Go写了个爬虫,只为蹲一场勇士vs篮网的NBA直播视频,结果我悟了
- 技术
- 2026-08-08 09:24:01
- 30
事情得从昨天下午说起
我正窝在沙发上刷手机,突然弹出条推送——勇士vs篮网,NBA直播视频,今天上午十点半,库里刚复出,欧文状态正热,这球不看简直亏大了,可问题是,我人在外面,电视遥控器在丈母娘手里,手机流量还剩下不到500MB。
你说巧不巧,我刚好在学Go语言,脑子一热:用Go写个爬虫,抓个直播源不就行了?
第一步:先别急着写代码,想清楚要抓什么
费曼学习法说得好,如果你不能简单地解释一件事,你就不够理解它,所以写代码之前,我先把需求拆了一遍:
- 我要的是一场NBA直播视频,不是文字直播,不是赛后集锦
- 对阵双方是勇士vs篮网,两个队都有流量担当
- 关键信息点:比赛时间、直播地址、清晰度选项、是否需要会员
我列了个表格,方便自己看:
| 信息项 | 优先级 | 说明 |
|---|---|---|
| 视频源地址 | P0 | 没有这个啥都白搭 |
| 开赛时间 | P1 | 过了时间就没意义 |
| 清晰度 | P1 | 720P就够,1080P更好 |
| 是否需要登录 | P2 | 影响我抓取的复杂度 |
第二步:Go语言写爬虫,真没你想的那么难
我用的方案很简单:net/http发请求,goquery解析HTML,正则表达式捞URL,这几行代码长得就像这样:
package main
import (
"fmt"
"net/http"
"regexp"
"strings"
)
func main() {
url := "https://example-live-site.com/nba-warriors-vs-nets"
resp, err := http.Get(url)
if err != nil {
fmt.Println("请求失败:", err)
return
}
defer resp.Body.Close()
// 用正则捞iframe或者video标签
body := make([]byte, resp.ContentLength)
resp.Body.Read(body)
re := regexp.MustCompile(`src="([^"]*\.m3u8[^"]*)"`)
matches := re.FindAllStringSubmatch(string(body), -1)
for _, m := range matches {
fmt.Println("找到直播源:", m[1])
}
}
代码只跑通了三次。 第一次是我自己写的一个测试页面,第二次是个公益直播站,第三次——也就是真正抓勇士vs篮网的时候——那个网站的直播源藏得深。
第三步:藏在JS里的直播源,最坑人
我以为发个GET请求就能拿到m3u8链接,结果打开页面源码一看,傻眼了,整个播放器是用JavaScript动态渲染的,HTML里根本没有视频地址,当时我盯着屏幕,就差把茶杯摔了。
后来我换了个思路:先抓HTML里的配置项,再去请求它背后的API接口,大概长这样:
// 模拟浏览器请求头
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
resp, err := client.Do(req)
加完User-Agent,响应体里终于出现了一个window.__INITIAL_STATE__的变量,里面藏着播放器配置,我再用字符串切割把playUrl字段抠出来——好家伙,是个带签名的*.m3u8地址,有效期半小时。
那一刻我突然觉得,Go语言处理字符串真的很容易让人上瘾,
strings.Split、strconv.Unquote一组合,啥都能抠出来。
第四步:直播视频拿到了,但比赛已经打完了
是的,你没看错,我花了一个半小时调试代码,等我把最终的播放链接放到VLC里打开的时候——
屏幕上已经是终场回放了。
勇士124:118篮网。 库里砍了32分,欧文也有29分,但最后时刻勇士的防守强度上来了,我盯着那个比分,又看了看我代码里打印出来的播放链接,突然笑了:这大概就是程序员的宿命——永远在追最新的数据,却总是慢一拍。
不过话说回来,这一趟折腾下来,也不是全无收获,我把这套抓视频源的逻辑整理成了一个简单的库,以后再遇到类似的需求,翻代码改个URL就能用。
最后说点实在的
如果你也想抓NBA直播视频,别指望在网上找到一个永久的固定地址。这些官方信号源通常都有防盗链机制,而且会频繁更换路径。 我的建议是:
- 用Go的
cron库定时抓取页面,检测新链接 - 把抓到的m3u8地址存到Redis里,设置过期时间
- 前端播放器用
video.js配合hls.js,直接喂地址就行
但说真的,比起写代码抓直播,打开电视看球赛才是最舒服的,写这个爬虫的下午,我错过了库里好几个三分球,下次勇士打篮网,我打算直接请假在家看,代码就留给半夜的比赛再用吧——那时候我反正睡不着。
