当前位置:首页 > 技术 > 正文

用Go写了个爬虫,只为蹲一场勇士vs篮网的NBA直播视频,结果我悟了

  • 技术
  • 2026-08-08 09:24:01
  • 37
摘要: 事情得从昨天下午说起我正窝在沙发上刷手机,突然弹出条推送——勇士vs篮网,NBA直播视频,今天上午十点半,库里刚复出,欧文状态正...

事情得从昨天下午说起

我正窝在沙发上刷手机,突然弹出条推送——勇士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.Splitstrconv.Unquote一组合,啥都能抠出来。

第四步:直播视频拿到了,但比赛已经打完了

是的,你没看错,我花了一个半小时调试代码,等我把最终的播放链接放到VLC里打开的时候——

屏幕上已经是终场回放了。

勇士124:118篮网。 库里砍了32分,欧文也有29分,但最后时刻勇士的防守强度上来了,我盯着那个比分,又看了看我代码里打印出来的播放链接,突然笑了:这大概就是程序员的宿命——永远在追最新的数据,却总是慢一拍。

不过话说回来,这一趟折腾下来,也不是全无收获,我把这套抓视频源的逻辑整理成了一个简单的库,以后再遇到类似的需求,翻代码改个URL就能用。

最后说点实在的

如果你也想抓NBA直播视频,别指望在网上找到一个永久的固定地址。这些官方信号源通常都有防盗链机制,而且会频繁更换路径。 我的建议是:

  • 用Go的cron库定时抓取页面,检测新链接
  • 把抓到的m3u8地址存到Redis里,设置过期时间
  • 前端播放器用video.js配合hls.js,直接喂地址就行

但说真的,比起写代码抓直播,打开电视看球赛才是最舒服的,写这个爬虫的下午,我错过了库里好几个三分球,下次勇士打篮网,我打算直接请假在家看,代码就留给半夜的比赛再用吧——那时候我反正睡不着。

用Go写了个爬虫,只为蹲一场勇士vs篮网的NBA直播视频,结果我悟了