文章目录
一、概要
这是一个基于 Python 的应用程序,主要用于获取和可视化 GitHub 上星标数超过 10000 的 Python 项目数据。通过 GitHub REST API 获取仓库数据,并使用 Plotly Express 生成交互式可视化图表,以直观的方式展示项目的受欢迎程度——以《Python从入门到实践 第三版》中的第二个项目为原型,做了优化和修改,实现分页提取数据功能。
二、展示图
三、架构流程
1. 整体架构
应用程序主要包含两个核心模块:
1)数据获取模块(fetch_github_repos)
2)数据可视化模块(create_visualization)
2. 工作流程
[GitHub API] -> [数据获取] -> [数据处理] -> [可视化生成] -> [HTML输出]
1)数据获取阶段:
- 构建 API 请求
- 发送 HTTP 请求
- 处理响应数据
- 错误处理和限流控制
2)可视化阶段:
- 数据预处理
- 图表配置
- 生成交互式图表
- 导出 HTML 文件
四、技术实现
1. 核心依赖
- requests:处理 HTTP 请求
- plotly.express:数据可视化
- time:处理延时和时间戳
2. 关键功能实现
1)数据获取模块
def fetch_github_repos(per_page=30, max_pages=10):
base_url = "https://api.github.com/search/repositories"
url = f"{base_url}?q=language:python+sort:stars+stars:>10000&per_page={per_page}&page={page}"
- 支持分页获取
- 包含查询参数配置
- 实现速率限制处理
- 异常处理机制
2)可视化模块
def create_visualization(repos, page_num):
# 数据处理
repo_links = [f"<a href='{repo['html_url']}'>{repo['name']}</a>" for repo in repos]
# 图表生成
fig = px.bar(x=repo_links, y=stars, title=title, labels=labels,
hover_name=hover_texts)
- 交互式条形图
- 支持链接跳转
- 悬停信息展示
- 自定义样式配置
五、具体细节
1. API 请求优化
- 使用 headers 指定 API 版本
- 实现请求重试机制
- 添加适当的请求间隔
2. 数据处理优化
- 链接格式化处理
- 数据清洗和转换
- 分页数据独立处理
3. 可视化优化
- 自定义字体大小
- 图表颜色配置
- 交互性能优化
- 分页展示策略
六、注意事项
1. API 限制
- GitHub API 有速率限制(未认证每小时 60 次)
- 需要适当的延时处理
- 建议使用 Personal Access Token 提高限制
2. 数据量控制
- 每页数据量建议控制在 100 条以内 【fetch_github_repos() 的参数:per_page:每页的仓库数量(最大100)】
- 总页数建议不超过 10 页 【fetch_github_repos() 的参数:max_pages:要获取的页数(建议不超过10页)】
- 注意内存使用效率
3. 可视化建议
- 避免单个图表数据过多
- 确保图表可读性
- 注意交互性能优化
七、完整代码
import requests
import plotly.express as px
import time
def create_visualization(repos, page_num):
"""为单页数据创建可视化图表"""
repo_links, stars, hover_texts = [], [], []
for repo_dict in repos:
# 将仓库名转换为链接
repo_name = repo_dict['name']
repo_url = repo_dict['html_url']
repo_link = f"<a href='{repo_url}'>{repo_name}</a>"
repo_links.append(repo_link)
stars.append(repo_dict['stargazers_count'])
# 创建悬停文本
owner = repo_dict['owner']['login']
description = repo_dict['description']
hover_text = f"{owner}<br />{description}"
hover_texts.append(hover_text)
# 可视化
title = f"Most-Starred Python Projects on GitHub (Page {page_num})"
labels = {'x': 'Repository', 'y': 'Stars'}
fig = px.bar(x=repo_links, y=stars, title=title, labels=labels,
hover_name=hover_texts)
fig.update_layout(
title_font_size=28,
xaxis_title_font_size=20,
yaxis_title_font_size=20
)
fig.update_traces(marker_color='SteelBlue', marker_opacity=0.6)
fig.write_html(f'Github_Stars_Page_{page_num}.html')
print(f'已生成第 {page_num} 页的可视化图表')
def fetch_github_repos(per_page=30, max_pages=3):
base_url = "https://api.github.com/search/repositories"
for page in range(1, max_pages + 1):
# 构建查询URL,包含分页参数
url = f"{base_url}?q=language:python+sort:stars+stars:>10000&per_page={per_page}&page={page}"
headers = {"Accept": "application/vnd.github.v3+json"}
try:
r = requests.get(url, headers=headers)
r.raise_for_status() # 检查是否有错误发生
# 检查API速率限制
if int(r.headers.get('X-RateLimit-Remaining', 0)) < 2:
reset_time = int(r.headers.get('X-RateLimit-Reset', 0))
sleep_time = max(reset_time - time.time(), 0)
print(f"即将达到API限制,等待 {sleep_time:.0f} 秒...")
time.sleep(sleep_time + 1)
response_dict = r.json()
current_repos = response_dict['items']
if not current_repos: # 如果没有更多结果,退出循环
break
print(f"已获取第 {page} 页数据,包含 {len(current_repos)} 个仓库")
# 为当前页面创建可视化
create_visualization(current_repos, page)
# 添加短暂延迟以避免触发GitHub的速率限制
time.sleep(1)
except requests.exceptions.RequestException as e:
print(f"获取数据时发生错误: {e}")
break
# 开始获取数据并生成可视化
print("开始获取GitHub仓库数据...")
fetch_github_repos()
print('所有页面的可视化图表已生成完成!')
八、总结
该应用程序通过合理的架构设计和技术实现,成功地实现了 GitHub 仓库数据的获取和可视化。其主要特点包括:
1)模块化设计:清晰的功能划分,便于维护和扩展
2)健壮性:完善的错误处理和限流机制
3)可视化效果:直观的数据展示和良好的交互体验
4)性能考虑:合理的分页处理和数据量控制
通过这个应用,用户可以直观地了解 GitHub 上最受欢迎的 Python 项目,为开源社区贡献了一个有价值的数据可视化工具。