查询GitHub上最流行的Python项目

一、效果图

查询返回GitHub上近100天内,星数>1000的用Python写的项目,按最大星数降序排列,返回前30个项目。点击对应蓝柱可直接跳转至仓库链接。

二、完整代码+注释

"""
GitHub趋势仓库数据可视化脚本
功能:获取最近100天星标数超过1000的Python仓库,生成水平柱状图展示前30名
"""

import requests
from datetime import datetime, timedelta
import matplotlib.pyplot as plt

def fetch_trending_repos():
    """
    从GitHub API获取趋势仓库数据
    返回:包含(仓库名称, 星标数)的元组列表,最多30条
    """
    # 计算时间范围:当前时间向前推100天
    since_date = (datetime.now() - timedelta(days=100)).strftime("%Y-%m-%d")
    
    # 构建API请求URL
    # q参数说明:
    # - created:>指定日期:筛选创建时间在指定日期之后的仓库
    # - language:python:指定编程语言为Python
    # - stars:>1000:筛选星标数超过1000的仓库
    # sort=stars:按星标数排序
    # order=desc:降序排列(从高到低)
    url = f'https://api.github.com/search/repositories?q=created:>{since_date}+language:python+stars:>1000&sort=stars&order=desc'
    
    # 设置请求头:模拟浏览器访问避免被拒绝
    headers = {'User-Agent': 'Mozilla/5.0'}
    
    # 发送GET请求(verify=False关闭SSL验证,生产环境不建议使用)
    response = requests.get(url,
                            headers=headers,
                            verify=False,
                            timeout=10)
    
    # 如果响应状态码不是200,抛出HTTP错误异常
    response.raise_for_status()

    # 解析JSON响应数据中的items字段
    repos = response.json().get('items', [])
    
    # 返回前30个仓库的(名称, 星标数)元组列表
    return [(repo['name'], repo['stargazers_count']) for repo in repos[:30]]

def plot_repos_data(repos_data):
    """
    数据可视化函数
    参数:repos_data - 包含(名称, 星标数)的元组列表
    """
    # 数据解包:将元组列表拆分为名称列表和星标数列表
    names = [x[0] for x in repos_data]  # 获取所有仓库名称
    stars = [x[1] for x in repos_data]  # 获取对应的星标数

    # 创建图形对象,设置画布尺寸为15x8英寸
    plt.figure(figsize=(15, 8))
    
    # 创建水平柱状图
    # barh参数说明:
    # - names: y轴标签(仓库名称)
    # - stars: 对应的柱状图长度(星标数)
    # - color: 柱状图颜色设置为天蓝色
    bars = plt.barh(names, stars, color='skyblue')
    
    # 设置坐标轴标签样式
    plt.xlabel('Stars Count', fontsize=12)   # x轴标签
    plt.ylabel('Repository Name', fontsize=12) # y轴标签
    
    # 设置图表标题,pad参数控制标题与图表的间距
    plt.title('Top Trending Python Repositories (Last 100 Days)', 
             fontsize=14, pad=20)
    
    # 反转y轴,使星标数最多的显示在最上方
    plt.gca().invert_yaxis()
    
    # 添加数据标签:在每个柱状图右侧显示具体星标数
    max_stars = max(stars)  # 获取最大值用于动态调整标签位置
    for bar in bars:
        width = bar.get_width()  # 获取当前柱状图的宽度(星标数)
        # 文字位置说明:
        # x坐标:柱状图右侧 + 最大值的2%(保持间距)
        # y坐标:柱状图垂直中心位置
        plt.text(width + max_stars*0.02, 
                 bar.get_y() + bar.get_height()/2,  # 计算垂直居中位置
                 f'{width:,}',  # 格式化数字添加千位分隔符
                 va='center')   # 垂直对齐方式设为居中

    # 自动调整子图参数,使整个图表适应画布
    plt.tight_layout()
    
    # 显示图表窗口
    plt.show()

if __name__ == "__main__":
    # 主程序入口
    repos_data = fetch_trending_repos()
    if repos_data:
        plot_repos_data(repos_data)
    else:
        print("没有找到趋势仓库数据")