背景
因为最近三年用的 Go 版本是 1.16,但最新的版本升级到了 1.23,很多依赖的三方包最新文件都已经升级,使用了泛型以及 GO 新版本的特性,导致我只能适配 Go1.16 的三方包旧版本,但这种问题发生的频率多了后,自然就感觉到了麻烦和落后,所以打算升级 Go 版本。
但升级到哪个版本?我的考虑的重心有一点在于主流 Go 服务在用哪个版本。
而社区环境,最佳的选择当然是 Github。
所以,首先目标是统计 Github 上 Go 项目中使用的版本分布情况。
统计目标
Github 上,Go 项目数量有一百六十多万:

抓取全部仓库数据进行统计,有点不现实。
所以我根据 starts 数量分析,最后确定抓取 stars 数量大于 200 的仓库数据:

总共只有一万多一点,所以主流和有价值的仓库占比,确实很少,大部分都是私人仓库而已。
数据抓取方式
Github 有开放 API,通过在 GitHub 账号重心生成 Token,就可以调用。


API 包括仓库搜索、仓库详情信息获取等,详细可以查阅 官方 API 文档。
使用 GITHUB_TOKEN 鉴权,调用 API 存在部分限制,比如:
- GitHub Search API 每次搜索,分页每页最多 100,每次查询结果分页,超过 1000 个结果就会报错 422。
- GitHub API 的速率限制为 5000 次请求/小时。
所以,在使用 API 时,结合统计目标的总数量,要考虑到上述两个限制。
数据抓取脚本
import requests
import base64
from collections import defaultdict
import time
import os
import csv
import configparser
from concurrent.futures import ThreadPoolExecutor, as_completed
# 读取配置文件
config = configparser.ConfigParser()
config.read('config.ini')
GITHUB_TOKEN = config['GITHUB']['TOKEN']
# 设置请求头,包含认证信息
headers = {
}
if GITHUB_TOKEN:
headers = {
'Authorization': f'token {
GITHUB_TOKEN}'
}
# 检查 API 速率限制
def check_rate_limit(headers):
remaining = int(headers.get('X-RateLimit-Remaining', 0))
reset_time = int(headers.get('X-RateLimit-Reset', time.time()))
if remaining == 0:
sleep_time = reset_time - time.time() + 1 # 等待到重置时间
print(f"API 请求达到速率限制,等待 {
sleep_time} 秒...")
time.sleep(sleep_time)
else:
print(f"剩余请求次数: {
remaining}")
# 构建 GitHub API 查询 URL
def build_search_url(query_params, page=1, per_page=100):
base_url = f"https://api.github.com/search/repositories"
query = '+'.join(query_params) # 将查询条件组装成字符串
url = f"{
base_url}?q={
query}&sort=stars&order=desc&per_page={
per_page}&page={
page}"
return url
# 获取 Go 仓库信息,增加重试机制以避免数据丢失
def search_go_repos(query_params, page=1, per_page=100, max_retries=3):
url = build_search_url(query_params, page=page, per_page=per_page)
retries = 0
while

最低0.47元/天 解锁文章
1436

被折叠的 条评论
为什么被折叠?



