You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用GitHub API v3及Python标准库获取指定时段分支的活跃用户及提交数

解决GitHub API获取指定分支、时间段活跃用户的问题

我来帮你搞定这个问题——你碰到的422错误是因为请求头设置错了,而且search/commits其实完全支持指定分支和时间段,只是你没用到正确的查询参数。下面一步步来解决:

1. 先修复HTTP 422错误

你的代码里请求头的写法搞反了,应该把Accept作为头名称,application/vnd.github.cloak-preview作为头的值,而不是反过来。正确的写法是:

q.add_header('Accept', 'application/vnd.github.cloak-preview')

2. 如何指定分支和时间段

search/commits的查询参数可以通过q字符串叠加多个条件,用+分隔:

  • 指定分支:添加branch:你的分支名,比如branch:main
  • 指定时间段:用committer-date:起始日期..结束日期,比如committer-date:2024-01-01..2024-06-01,也可以用>=/<=来限定单边范围

比如查询octocat/Spoon-Knife仓库main分支在2024年上半年的提交,完整的q参数是:
repo:octocat/Spoon-Knife+branch:main+committer-date:2024-01-01..2024-06-01

3. 完整Python实现(基于标准库)

下面的代码会完成这些事:

  • 遍历所有分页的提交结果(API每页最多返回100条)
  • 统计每个用户的提交次数
  • 按提交次数降序排序,取前30位活跃用户
import urllib.request
import json
from collections import defaultdict

def get_top_active_users(repo_owner, repo_name, branch, start_date, end_date, top_n=30):
    base_url = "https://api.github.com/search/commits"
    # 构建查询参数
    query = f"repo:{repo_owner}/{repo_name}+branch:{branch}+committer-date:{start_date}..{end_date}"
    url = f"{base_url}?q={query}&per_page=100"  # 每页取最大100条
    
    commit_counts = defaultdict(int)
    page = 1
    
    while url:
        try:
            req = urllib.request.Request(url)
            # 设置正确的Accept头
            req.add_header('Accept', 'application/vnd.github.cloak-preview')
            # 有GitHub令牌的话可以加上,提升速率限制:req.add_header('Authorization', 'token 你的令牌')
            
            response = urllib.request.urlopen(req)
            data = json.loads(response.read().decode('utf-8'))
            
            # 统计每个用户的提交数
            for item in data['items']:
                author_login = item['author']['login'] if item['author'] else 'unknown'
                commit_counts[author_login] += 1
            
            # 处理分页:获取下一页的URL
            links = response.getheader('Link')
            url = None
            if links:
                for link in links.split(','):
                    if 'rel="next"' in link:
                        url = link.split(';')[0].strip('<>')
            page += 1
            
        except urllib.error.HTTPError as e:
            print(f"HTTP错误 {e.code}: {e.read().decode('utf-8')}")
            break
    
    # 按提交次数降序排序,取前top_n
    sorted_users = sorted(commit_counts.items(), key=lambda x: x[1], reverse=True)[:top_n]
    return sorted_users

# 示例调用
if __name__ == "__main__":
    top_users = get_top_active_users(
        repo_owner="octocat",
        repo_name="Spoon-Knife",
        branch="main",
        start_date="2024-01-01",
        end_date="2024-06-01"
    )
    
    print("Top 30活跃用户及提交次数:")
    for idx, (login, count) in enumerate(top_users, 1):
        print(f"{idx}. {login}: {count}次提交")

关键注意点

  • 速率限制:未认证的GitHub API请求每小时最多60次,如果你需要更高的调用额度,建议添加GitHub个人访问令牌(在请求头里加Authorization: token 你的令牌),认证后每小时最多5000次。
  • 无关联用户的提交:有些提交可能没关联GitHub账号(比如用邮箱提交但未绑定账号),代码里会标记为unknown,你可以根据需求调整这部分逻辑。
  • 结果上限:search/commits最多返回1000条结果,如果目标时间段内提交超过1000条,这个方法可能无法统计全部(GitHub的限制)。这种情况下可以改用GET /repos/{owner}/{repo}/commits接口遍历分支的所有提交,虽然分页处理更繁琐,但没有1000条的限制。

内容的提问来源于stack exchange,提问作者 Sergisson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:45:39