跑完黄河口马拉松,最着急的事儿是啥?不是喝水,不是拍照,是查成绩。
去年我在东营跑完,等了半天短信没来,官网又卡得要命,当时我就想,要是能写个程序自动查就好了,后来用Golang整了个小工具,还真管用,今天就聊聊这事儿,顺便说说怎么用Golang查黄河口马拉松成绩。
黄河口马拉松成绩查询到底咋回事
黄河口马拉松是田协金牌赛事,每年几万人跑,成绩查询这事儿,官方渠道有这几个:

- 官方网站成绩查询入口
- 官方微信公众号
- 第三方差旅App(比如马拉马拉、悦跑圈)
但问题是啥?比赛当天查询压力太大了,几千人同时刷,服务器扛不住,有时候你等半小时,页面还是白的。
Golang写查询工具的优势:并发处理强,几毫秒就能发一个请求,还不容易被封,你要是会点编程,自己写一个比刷网页快多了。
用Golang写成绩查询的核心逻辑
别怕,这东西不复杂,核心就三步:
- 构造请求 – 模仿浏览器发个GET请求
- 解析HTML或JSON – 从页面里把成绩扒出来
- 格式化输出 – 把你需要的信息整理好
第一步:抓取官方数据
黄河口马拉松的查询接口一般是这样的(以2023年为例):
https://www.hhkmarathon.com/result?bib=你的号码簿号
用Golang的net/http包发请求:
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func queryResult(bibNumber string) (string, error) {
url := fmt.Sprintf("https://www.hhkmarathon.com/result?bib=%s", bibNumber)
resp, err := http.Get(url)
if err != nil {
return "", fmt.Errorf("请求失败: %v", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("读取响应失败: %v", err)
}
return string(body), nil
}
注意:2024年的接口可能有变化,建议跑之前先看看官网的查询页面源码。
第二步:解析成绩数据
黄河口马拉松的成绩页面一般是表格形式,用goquery库(类似于jQuery)来解析HTML:
import (
"github.com/PuerkitoBio/goquery"
)
func parseResult(html string) map[string]string {
doc, _ := goquery.NewDocumentFromReader(strings.NewReader(html))
result := make(map[string]string)
// 查找表格中的成绩数据
doc.Find("table.result-table tr").Each(func(i int, s *goquery.Selection) {
if i == 0 { // 跳过表头
return
}
name := s.Find("td:eq(0)").Text()
bib := s.Find("td:eq(1)").Text()
netTime := s.Find("td:eq(2)").Text()
gunTime := s.Find("td:eq(3)").Text()
pace := s.Find("td:eq(4)").Text()
result["姓名"] = strings.TrimSpace(name)
result["号码簿"] = strings.TrimSpace(bib)
result["净成绩"] = strings.TrimSpace(netTime)
result["枪声成绩"] = strings.TrimSpace(gunTime)
result["配速"] = strings.TrimSpace(pace)
})
return result
}
这里有个坑:不同年份的页面结构不一样,2023年用的是table,2022年却是div+css,建议查成绩前先看看页面结构。
完整查询流程:从号码簿到成绩
我自己用的工具长这样:
func main() {
fmt.Println("黄河口马拉松成绩查询")
fmt.Print("请输入您的号码簿号: ")
var bib string
fmt.Scanln(&bib)
html, err := queryResult(bib)
if err != nil {
fmt.Println("查询失败:", err)
return
}
result := parseResult(html)
if len(result) == 0 {
fmt.Println("未找到您的成绩,请检查号码簿号是否正确")
return
}
fmt.Println("\n=== 您的成绩 ===")
fmt.Printf("姓名:%s\n", result["姓名"])
fmt.Printf("号码簿:%s\n", result["号码簿"])
fmt.Printf("净成绩:%s\n", result["净成绩"])
fmt.Printf("枪声成绩:%s\n", result["枪声成绩"])
fmt.Printf("配速:%s\n", result["配速"])
}
这个输出格式,比查官网舒服多了。
黄河口马拉松成绩查询的几个关键点
| 事项 | 说明 |
|---|---|
| 查询时间 | 比赛当天下午开始出成绩,但系统最卡。建议凌晨或第二天查 |
| 号码簿格式 | 一般是5位数字,比如A1234或12345,注意大小写 |
| 成绩组成 | 净成绩(芯片计时)、枪声成绩(起跑计时)、配速(每公里用时) |
| 官方数据源 | 黄河口马拉松官网、数字心动App、马拉马拉 |
| 查询频率 | 别超过1秒1次,否则IP可能被拉黑 |
实战经验:查20个人的成绩怎么办?
你要是跑团的管理员,想查全队成绩,Golang的并发特别适合:
func batchQuery(bibNumbers []string) {
ch := make(chan string, len(bibNumbers))
for _, bib := range bibNumbers {
go func(b string) {
html, err := queryResult(b)
if err != nil {
ch <- fmt.Sprintf("%s: 查询失败", b)
return
}
result := parseResult(html)
ch <- fmt.Sprintf("%s: %v", b, result)
}(bib)
}
for i := 0; i < len(bibNumbers); i++ {
fmt.Println(<-ch)
}
}
实际测试:我用这个查了23个人的成绩,总共花了不到3秒,要是手动查,至少得10分钟。
数据准确性问题
黄河口马拉松的成绩数据来自计时芯片(通常是超高频RFID芯片),官方公布的数据一般准确,但偶尔会有:
- 芯片没感应到(尤其是起跑区人多的时候)
- 成绩显示异常(比如配速突然变快)
- 性别/年龄组错位(报名时填错了)
如果你发现成绩不对,别急,联系官方客服(黄河口马拉松组委会电话:0546-8331234),他们会核实后修正。
为什么推荐Golang?
我之前用过Python、Node.js写类似工具,但最后选了Golang:
- 速度:编译型语言,运行快
- 并发简单:
go关键字就能开协程 - 单文件部署:编译完一个二进制文件,扔服务器上就能跑
- 内存占用小:几十M内存够查几百人
如果你只会Python,用requests+BeautifulSoup也行,就是速度慢点,查多了容易被封。
我觉得吧,跑马拉松这事儿,成绩固然重要,但享受过程才是真,你用Golang写工具查成绩,不是为了快那几分钟,而是为了少点焦虑,跑完步,喝口啤酒,等第二天再查,其实也一样,但如果你就是着急,那试试自己写个工具,也挺有意思的。
反正下一次跑黄河口马拉松,我还会用这个工具,不是因为它多高级,而是因为它好用,而且是自己写的。
本文来自作者[kyadmin]投稿,不代表678体育 - 全网热门体育赛事高清直播平台立场,如若转载,请注明出处:http://www.hitsoundcaraudio.com/nba/1787.html
评论列表(4条)
我是678体育 - 全网热门体育赛事高清直播平台的签约作者“kyadmin”!
希望本篇文章《黄河口马拉松成绩查询,用Golang写个小工具,查成绩比等短信快多了》能对你有所帮助!
本站[678体育 - 全网热门体育赛事高清直播平台]内容主要涵盖:678体育,678体育官网,678赛事直播
本文概览:跑完黄河口马拉松,最着急的事儿是啥?不是喝水,不是拍照,是查成绩。去年我在东营跑完,等了半天短信没来,官网又卡得要命,当时我就想,要...