ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

HelloGitHub 的 GitHub Bot 脚本:用 GitHub Events API 自动收集 Star 项目并邮件推送的完整实现

HelloGitHub 的 GitHub Bot 脚本:用 GitHub Events API 自动收集 Star 项目并邮件推送的完整实现 技术博客文档知识库【免费下载链接】HelloGitHub:octocat: 分享 GitHub 上有趣、入门级的开源项目。Share interesting, entry-level open source projects on GitHub.项目地址https://gitcode.com/GitHub_Trending/he/HelloGitHub点击查看免费下载兴趣是最好的老师HelloGitHub 就是帮你找到兴趣《HelloGitHub 月刊》的内容主要来自 GitHub 上有趣、入门级的开源项目而 script/github_bot/README.md 所描述的 GitHub Bot 脚本正是这套月刊选题流水线中负责“收集素材”的第一环。本文将结合 github_bot.py 的完整源码从运行步骤、参数配置到底层 API 调用链逐层拆解让你掌握如何通过 GitHub 官方 Events API 采集指定账号的 Star 事件、按规则过滤、拉取实时 Star 数并生成 HTML 邮件定时推送的整套自动化方案。脚本定位月刊选题的自动化数据源在 HelloGitHub 仓库中月刊内容的生产链路分为两段收集素材由本仓库 script/github_bot 下的 Bot 脚本完成它自动关注一批高质量 GitHub 账号收集这些账号每天 Star 的项目再按 Star 数排序输出生成月刊由 script/make_content/make_content.py 完成它读取template.md模板与各期contentXX.md内容文件批量生成content/HelloGitHubXX.md月刊成品仓库中现存第 1124 期见 content 目录。因此github_bot 是整条流水线的“原料采集器”它不负责写作只负责把“今天哪些项目被高质量账号点了 Star”这件事变成一份按 Star 数排序的清单再通过邮件推送给月刊作者审阅。运行步骤三步跑起 Botscript/github_bot/README.md 给出的运行步骤非常精简只有三步1. 安装依赖pip install -r requirements.txt依赖文件 script/github_bot/requirements.txt 中只有一个包requests。整个脚本的网络请求GitHub API 与邮箱 SMTP 之外的 HTTP 操作全部依赖它完成。2. 配置脚本参数打开 github_bot.py 顶部的配置区第 2651 行按实际环境填写# github帐号 ACCOUNT { username: , password: } # 发送邮件邮箱的信息 MAIL { mail: , # 发送邮件的邮箱地址 username: , password: , host: smtp.qq.com, port: 465 } # 接收邮件的邮箱地址 RECEIVERS [] # qq邮件服务文档http://service.mail.qq.com/cgi-bin/help?id28除了 README 展示的ACCOUNT、MAIL、RECEIVERS三组配置源码中还额外定义了两个影响采集行为的关键参数# 几天前 DAY 1 # 项目stars临界值 STARS 100各参数的完整说明如下表参数类型作用ACCOUNT[username]/ACCOUNT[password]strGitHub 账号与密码用于调用 API 时的 HTTP Basic Auth 鉴权源码第 7980 行MAIL[mail]str发送邮件的邮箱地址同时作为 SMTP 发件人源码第 190 行MAIL[username]/MAIL[password]strSMTP 登录凭据QQ 邮箱通常为授权码而非登录密码MAIL[host]/MAIL[port]str / intSMTP 服务器地址与端口默认smtp.qq.com:465对应 SSL 加密连接RECEIVERSlist接收邮件的邮箱地址列表可配置多个收件人DAYint只统计最近DAY天内发生的 Star 事件默认 1 天源码第 110111 行STARSint项目 Star 数临界值低于该值的项目会被过滤掉默认 100源码第 51 行注意脚本使用SMTP_SSL加密连接这是 QQ 邮箱的要求详见源码第 204 行注释因此MAIL[port]必须与 SSL 端口465配套使用。3. 运行脚本python github_bot.py脚本入口在源码第 211213 行if __name__ __main__: content make_content() send_email(RECEIVERS, content)执行流程为先make_content()完成“拉取数据 → 过滤 → 加工 → 生成邮件 HTML”再send_email()把结果发送给RECEIVERS中的全部收件人。过程中产生的错误日志会按 README 开发日志中 2016-09-29 的记录写入到脚本同目录下的bot_log.txt文件由源码第 1823 行的logging.basicConfig配置采用追加模式filemodea。源码级原理拆解从 API 请求到邮件发出三步运行背后是四段环环相扣的数据处理流程。下面逐一对应源码解读。第一环拉取关注账号的 Star 事件get_data / get_all_data脚本的数据源是 GitHub 官方 Events API端点定义在源码第 3133 行API { events: https://api.github.com/users/{username}/received_events.format(usernameACCOUNT[username]) }get_data(page1)第 7087 行向该端点发起分页请求并使用ACCOUNT的账号密码做 HTTP Basic Authresponse requests.get(API[events]args, auth(ACCOUNT[username], ACCOUNT[password])) status_code response.status_code if status_code 200: resp_json response.json() return resp_json else: logging.error(请求 event api 失败, status_code) return []需要说明的是这里请求的是received_events即当前账号所关注following的用户产生的公开事件流。也就是说ACCOUNT[username]本身充当了“我关注了哪些高质量账号”的载体——被关注账号的 Star 行为会出现在这个事件流中这正是开发日志 2017-04-06 中“新注册帐号 521hellogithub 用于获取每天的数据”的原因用一个专用账号专门关注一批高质量账号就能批量拿到它们的 Star 动态。get_all_data()第 90101 行负责拉满全部事件all_data_list [] for i in range(10): response_json get_data(i1) if response_json: all_data_list.extend(response_json) return all_data_list循环 10 次、每页 30 条正好对应源码注释和 README 开发日志 2017-04-06 中记录的限制GitHub API 规定 event 每页最多 30 条、总计最多获取 300 条。这是脚本采集量的物理上限也是后来 GitHub API 更新后脚本随之适配的边界。第二环按 WatchEvent 与时间窗口过滤check_condition / analyze拿到 300 条原始事件后analyze()第 122131 行遍历每条事件交给check_condition()第 104119 行逐一判定是否入选def check_condition(data): create_time datetime.datetime.strptime( data[created_at], %Y-%m-%dT%H:%M:%SZ) datetime.timedelta(hours8) date_condition create_time (datetime.datetime.now() - datetime.timedelta(daysDAY)) if (data[type] WatchEvent) and date_condition: # 不统计自己项目的star事件 if data[payload][action] started and \ ACCOUNT[username] not in data[repo][name]: data[date_time] create_time.strftime(%Y-%m-%d %H:%M:%S) return True else: return False过滤规则有三条对应 README 开发日志中的历次迭代事件类型必须是WatchEventGitHub 的 Star 行为在 Events API 中即表现为WatchEventpayload 的 action 为started这是自 2016-09-05 实现“获取关注的用户 star 的项目”起就确定的核心判定时间窗口为最近DAY天GitHub 返回的created_at是 UTC 时间脚本先解析为时间对象并8小时转为北京时间源码第 108109 行再与“当前时间减去DAY天”比较不统计自己的项目通过ACCOUNT[username] not in data[repo][name]排除账号 Star 自己仓库的情况这条规则对应开发日志 2016-09-29 的“GitHub 今日热点项目不统计自己的项目”。通过判定的数据会额外写入一个date_time字段北京时间格式化字符串供后续生成邮件内容使用。第三环拉取实时 Star 数并按临界值排序get_stars过滤出的项目只是“被高质量账号 Star 了”还需要知道它们当下的热度。get_stars()第 134162 行对每个项目调用仓库 API 获取实时 Star 数repo_stars requests.get(fi_data[repo][url], timeout2).json() if repo_stars: project_info[repo_stars] int(repo_stars[stargazers_count]) else: project_info[repo_stars] -1其中fi_data[repo][url]是事件数据里自带的仓库 API 地址如https://api.github.com/repos/owner/name请求带上timeout2防止单点拖慢整体失败时repo_stars记为-1并写入bot_log.txt警告日志第 153156 行。随后执行两层处理临界值过滤第 158160 行repo_stars STARS的项目才保留-1获取失败的项目也保留以免漏掉数据排序第 161 行sorted(..., keyitemgetter(repo_stars), reverseTrue)按 Star 数从高到低排列对应开发日志 2016-09-24 的“实现根据 star 数量从高到低展示”。同时get_stars()还会把每个项目加工成邮件所需的字段结构用户名、用户主页、头像地址、仓库名、仓库地址、Star 时间和 Star 数第 140146 行。第四环生成 HTML 表格并发送邮件make_content / send_emailmake_content()第 165183 行把加工后的项目列表逐行格式化成 HTML 表格行拼接后交给邮件发送邮件正文的骨架由CONTENT_FORMAT模板第 5667 行定义CONTENT_FORMAT table border2 aligncenter tr th头像/th th用户名/th th项目名/th thstarred 日期/th th项目 star 数量/th /tr {project_info_string} /table 每一行数据的 HTML 形如源码第 174181 行tr tdimg src{avatar_url} width32px/img/td tda href{user_url}{user}/a/td tda href{repo_url}{repo_name}/a/td td{date_time}/td td{repo_stars}/td /trsend_email()第 186209 行负责最终投递message MIMEText( CONTENT_FORMAT.format(project_info_string.join(email_content)), html, utf-8 ) message[From] Header(uGitHub 机器人, utf-8) message[To] Header(u削微寒, utf-8) subject u今日 GitHub 热点 message[Subject] Header(subject, utf-8)邮件使用MIMEText构造 HTML 正文、Header指定 UTF-8 编码的发件人/收件人/主题主题为“今日 GitHub 热点”。发送阶段第 203209 行的关键实现smtp_obj smtplib.SMTP_SSL() # qq邮箱要求是https连接所以需要用SMTP_SSL smtp_obj.connect(MAIL[host], MAIL[port]) # 设置SMTP地址和端口号 smtp_obj.login(MAIL[username], MAIL[password]) smtp_obj.sendmail(sender, receivers, message.as_string())可以看到这里特意使用smtplib.SMTP_SSL()建立加密连接这正是配置中port: 465的配套前提登录失败等异常会被捕获并记录到bot_log.txt。开发日志脚本的演进脉络script/github_bot/README.md 用“开发日志”记录了脚本从无到有的四次关键迭代结合源码可以还原出完整演进时间线时间变更对应源码位置2016-09-05实现请求 GitHub Api 获取关注的用户 star 的项目、过滤内容、定时发邮件API[events]第 31-33 行、get_data/check_condition/send_email2016-09-24实现根据 star 数量从高到低展示get_stars末尾排序第 161 行2016-09-29GitHub 今日热点项目不统计自己的项目错误日志放到脚本同目录下check_condition中的排除逻辑第 114-115 行、logging.basicConfig第 18-23 行2017-03-28增加收集项目 star 临界值STARS 100第 51 行及其过滤逻辑第 158-160 行2017-04-06GitHub Api 更新event 最多获取 300 条新注册帐号 521hellogithub 用于获取每天的数据get_all_data的 10 次分页循环第 90-101 行这组日志是理解脚本设计约束的一手资料get_all_data为什么只循环 10 次、为什么需要单独注册专用采集账号、STARS临界值参数从何而来都能在源码中找到对应实现。已知局限与 TodoREADME 末尾列出了脚本作者规划的后续方向从中也能看出这套方案当前的边界获取 explore 页的数据目前数据源只有received_events关注账号的事件流GitHub Explore 页的推荐项目尚未纳入采集异步请求获取 star 数get_stars目前是串行同步请求每个仓库的 API第 148 行当候选项目较多时耗时明显异步化是明确的优化方向自己项目的数据统计当前实现刻意排除了自己的项目第 114-115 行作者计划后续补充自身仓库的数据统计能力。另外需要留意两个与当前 GitHub 生态的差异点若要在今天复跑该脚本需自行适配认证方式脚本使用账号密码做 Basic Auth而现代 GitHub API 已推荐使用 Personal Access TokenAuthorization: token TOKEN或Bearer代替密码API 限额与字段Events API 的 300 条上限是 2017 年的约束如今 Unauthenticated 请求的速率限制、事件类型字段StarEvent vs WatchEvent都已变化运行前应以 script/github_bot/README.md 标注的“2017-04-06”时间节点为前提评估。总结github_bot 是一个麻雀虽小、五脏俱全的 GitHub 数据采集范例它用不到 220 行代码完成了“Events API 分页拉取 → 事件类型/时间窗口/自项目三重过滤 → 实时 Star 数加工与排序 → HTML 邮件生成与 SMTP_SSL 投递”的完整闭环。对于想实现“追踪高质量账号动态”“自动化选题采集”“邮件定时推送”等场景的开发者这份 github_bot.py 源码连同其 README 中的配置说明与开发日志是一份可直接对照复用的实战参考。赞分享技术博客文档知识库【免费下载链接】HelloGitHub:octocat: 分享 GitHub 上有趣、入门级的开源项目。Share interesting, entry-level open source projects on GitHub.项目地址https://gitcode.com/GitHub_Trending/he/HelloGitHub点击查看免费下载相关推荐如何利用GitHub Actions实现自动化论文推送系统完整指南如何利用GitHub Actions实现自动化论文推送系统完整指南 Algorithm Practice in Industry项目是一个专注于搜索、推荐、广AI 应用大模型数据分析从0到1搭建持续部署流水线Git-Auto-Deploy实战教程从0到1搭建持续部署流水线Git Auto Deploy实战教程 Git Auto Deploy是一款用Python编写的轻量级HTTP服务器能够在Git推运维后端EasyGank源码分析从项目启动到网络请求的完整执行流程EasyGank源码分析从项目启动到网络请求的完整执行流程 EasyGank是一个基于Rx系列和MVP模式构建的Android项目框架通过本文你将了解其从应上一篇Material for MkDocs 内置搜索插件中文分词支持jieba配置与源码解析下一篇数据科学生命周期入门采集、处理与维护三阶段实战解析Data-Science-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表