欧冠时间可以c77点tv—用Go语言写个比赛提醒器,顺便聊聊看球那点事
- 在线德州扑克
- 2026-08-22 13:19:56
- 37
为什么我半夜爬起来写这个
昨晚又熬夜看欧冠了,老婆问我“几点开球”,我脱口而出“c77点tv上写着呢”——结果被她白了一眼,说实话,每次查欧冠时间,我手机里那几个体育App推送总是不准时,要么提前两小时轰炸我,要么比赛都开始了才慢悠悠弹个通知,后来我琢磨着,自己是个写Go的,干嘛不搞个小工具,把欧冠时间抓下来,存本地,到点提醒我?说干就干,这篇就记录一下我折腾的过程,顺便聊聊怎么用Go处理这种“时间敏感型”的小需求。
先解决“时间从哪来”的问题
看球的人都知道,欧冠赛程不是固定的,小组赛、淘汰赛,每个比赛日开球时间可能差出好几个小时,我之前试过手动去UEFA官网翻,但那个表格做得太反人类了,后来发现有个叫football-data.org的公开API,免费额度够用,返回的是JSON格式,里面utcDate字段就是标准的ISO8601时间字符串。
{
"utcDate": "2025-04-09T19:45:00Z",
"status": "TIMED",
"matchday": 8
}
这玩意儿直接丢给Go的time.Parse处理就行,但这里有个坑——你拿到的UTC时间,得转成你本地时区,不然你人在北京,晚上三点开球,你手机显示下午三点,那不乱套了吗?
Go代码里怎么处理时区
我用Go写了个小函数,专门把UTC转成东八区:
func toLocal(utcStr string) (time.Time, error) {
t, err := time.Parse(time.RFC3339, utcStr)
if err != nil {
return time.Time{}, err
}
loc, _ := time.LoadLocation("Asia/Shanghai")
return t.In(loc), nil
}
就这么几行,但解决了我最头疼的“看错时间”问题,以前用手机日历手动加,总得心算“UTC+8”,现在程序帮我算好了,而且Go的time包自带时区数据库,哪怕你人在纽约、伦敦,改个LoadLocation参数就行,不用自己维护一堆偏移量。
提醒功能,我直接用了个最简单粗暴的方案
说实话,我不喜欢装一堆依赖,提醒功能我考虑过用cat(对,就是gocron那类库),但后来想想,就为了一个提醒,没必要引这么多包,我直接写了个死循环,每分钟检查一次当前时间,和比赛时间比较,提前15分钟往我手机发个系统通知——用的beep库,就是终端里响两声,够用了,你要是也想这么干,代码大致长这样:
for {
now := time.Now()
if now.After(matchTime.Add(-15 * time.Minute)) && now.Before(matchTime) {
beep.Beep(beep.Default)
break
}
time.Sleep(1 * time.Minute)
}
别笑,真能用,虽然丑了点,但胜在零依赖,编译完一个二进制丢服务器上就跑,你要是有更高的追求,可以接个Telegram bot或者钉钉机器人,但那又是另一个坑了,今天先不聊。
表格:我这个赛季手动记录的开球时间(节选)
我顺手把最近几场关键比赛的当地时间和北京时间列了个表,方便你感受下什么叫“阴间时间”:
| 比赛阶段 | 当地时间(欧洲) | 北京时间(c77点tv标注) | 我的闹钟设置 |
|---|---|---|---|
| 小组赛第一轮 | 晚上 18:45 CET | 凌晨 00:45 | 00:30 响 |
| 小组赛第二轮 | 晚上 21:00 CET | 凌晨 03:00 | 02:45 响 |
| 淘汰赛首回合 | 晚上 20:00 GMT | 凌晨 04:00 | 03:45 响 |
| 决赛 | 晚上 21:00 CEST | 凌晨 03:00 | 02:45 响 |
你看,除了极少数周末场次,基本全是后半夜,这就更凸显出“自动提醒”的价值了——人脑记不住这些乱七八糟的时差换算。
c77点tv”这个关键词,我多说两句
你可能注意到我文章里反复提“c77点tv”,其实这不算什么官方权威源,就是哥们儿之间口口相传的一个看球时间查询的站点,界面挺简洁,没有满屏弹窗广告,我写代码抓数据的时候,也参考过它上面的时间标注,发现它这个时间显示逻辑做得还算良心——默认给你转成你本机时区,不像某些网站非要你自己选,你要是用Go写爬虫去抓它,记得加个User-Agent,不然容易被封IP,我这边倒是没遇到问题,可能碰巧它没针对Go的库做反爬。
再分享一个我踩过的坑
如果你和我一样,想用goquery去解析那个网站,注意了,它页面上时间是用<time>标签包裹的,但里面还有个data-timestamp属性,是Unix毫秒时间戳,我当时没细看,直接抓了文本,结果拿到个“19:45”这种带格式的字符串,还得自己拼日期,麻烦死了,后来改用属性值,一行代码搞定:
timestamp, _ := strconv.ParseInt(attrVal, 10, 64) localTime := time.UnixMilli(timestamp).In(loc)
比我想的省事多了,所以说,看网页结构的时候,多看看标签里的属性,别光盯着内容。
代码跑起来的样子
我把它设成开机自启了,每天凌晨跑一下,拉取当天和明天的赛程,存到data.json里,早上起来瞄一眼,就知道今晚有没有球,几点球,说实话,比起那种动不动就推送几十条新闻的App,我更喜欢这种“自己掌控”的感觉,可能这就是程序员的一点点执念吧——能用代码解决的,绝不动手查。
对了,昨天我又盯了一场,托特纳姆主场那个,明明是晚上9点开球,我提前半小时端了杯咖啡坐电脑前,结果看到比赛因故推迟了15分钟,那会儿我正对着屏幕骂骂咧咧呢,后来想想,这也算熬夜看球的乐趣之一吧——你永远不知道除了比分,还有什么会出乎意料。
