☰
GitHub Actions 自动化签到:从手动打卡到定时任务
2026/10/13 16:06:26 网站建设 项目流程

1. 从手动打卡到自动化签到的真实痛点

每天早上八点,闹钟一响,第一件事不是刷牙洗脸,而是摸手机打开某个网站或者小程序,找到打卡入口,点进去,填体温、填健康状况、勾选承诺书、提交。整个过程熟练的话两分钟,不熟练或者网络卡顿的时候五分钟都搞不定。更让人崩溃的是,有时候忙起来彻底忘了这回事,等想起来的时候已经是晚上十一点,赶紧补卡,心惊胆战怕被通报。

这个场景我相信很多人都经历过。不管是学校的健康信息填报,还是某些平台的每日签到领积分,本质上都是重复性、低价值、但又不得不做的机械操作。作为一个写了多年代码的人,我的第一反应永远是:这种事能不能让机器替我干?

答案是肯定的。而且方案比你想的要简单得多——GitHub Actions。你不需要买服务器,不需要租云主机,不需要配置什么复杂的定时任务框架。GitHub 本身就提供了免费的定时触发能力,你只需要写一个配置文件,把你的打卡逻辑塞进去,它就会在每天你指定的时间自动帮你跑一遍。跑完还能给你发通知,告诉你成功了还是失败了。

这篇文章要聊的就是这套方案的完整落地过程。我会从最核心的原理讲起,把每一步为什么这么做、坑在哪里、怎么绕过去都说清楚。适合有基本 Git 操作经验、想让重复劳动自动化的朋友。哪怕你之前没写过 GitHub Actions,跟着走也能跑通。

注意:本文讨论的是个人效率工具的技术实现思路,所有案例均为模拟场景,请确保你的自动化操作符合所在平台的使用条款。

2. 为什么选 GitHub Actions 而不是其他方案

2.1 常见自动化方案的横向对比

在决定用 GitHub Actions 之前,我认真评估过几种主流方案。这里把我的对比思路分享出来,方便你根据自己的情况做选择。

方案成本技术门槛稳定性维护成本适合人群
本地电脑定时脚本零低差(关机就断)低有常开电脑的人
云服务器 + cron每月几十元中好中有运维基础的人
树莓派等小型设备一次性硬件成本中高一般(断电断网)中喜欢折腾硬件的人
GitHub Actions免费低好极低有 GitHub 账号的开发者
第三方自动化平台免费额度有限低一般低不想碰代码的人

本地电脑跑脚本的问题很明显:你得保证那个时间点电脑是开着的,网络是通的,脚本没被误删。我试过在自己笔记本上挂定时任务,结果出差三天,打卡断了三天,回来被提醒了。云服务器倒是稳定,但一年下来也是一笔开销,就为了跑一个每天两分钟的脚本,性价比太低。

GitHub Actions 的优势在于:它天然就是为定时任务设计的。你只需要一个公开仓库(私有仓库也有免费额度),把脚本放进去,配置好 cron 表达式,剩下的交给 GitHub 的服务器。它不会因为你关机而停止,不会因为你换网络而中断,而且完全免费。

2.2 GitHub Actions 的定时触发机制

GitHub Actions 的定时触发靠的是on.schedule事件,底层用的是标准的 cron 表达式。但这里有一个很多人第一次用都会踩的坑:GitHub 的 cron 用的是 UTC 时间,不是北京时间。

北京时间是 UTC+8,所以如果你想让任务在北京时间早上 7 点执行,cron 表达式应该写成 UTC 的 23 点(前一天)。比如:

on: schedule: - cron: '0 23 * * *'

这行配置的意思是每天 UTC 23:00 触发,对应北京时间早上 7:00。

还有一个更隐蔽的坑:GitHub Actions 的定时任务并不保证精确执行。官方文档明确说了,在高负载时段,任务可能会延迟几分钟甚至更久。我实测下来,延迟通常在 3 到 15 分钟之间。所以如果你打卡有严格的时间窗口,建议把触发时间设得稍微早一点,留出缓冲。

另外,定时任务只会在默认分支上生效。如果你的仓库默认分支是main,那 workflow 文件必须放在main分支的.github/workflows/目录下,放在其他分支上不会触发。

2.3 免费额度的真实消耗情况

很多人担心免费额度不够用。我算一笔账:GitHub 对公开仓库的 Actions 是完全免费的,不消耗额度。对私有仓库,免费账户每月有 2000 分钟的额度。一个打卡脚本单次运行通常不超过 1 分钟,一个月 30 次也就是 30 分钟,远远用不完。

但要注意,如果你的脚本里包含了安装依赖、编译等步骤,单次运行时间可能会拉长到 2-3 分钟。即便如此,一个月也就 60-90 分钟,依然在安全范围内。真正消耗额度的是那些需要跑大型构建、测试套件的项目,单纯的打卡签到脚本完全不用担心。

提示:如果你的仓库是私有的,建议在 workflow 里设置timeout-minutes,防止脚本卡死导致额度被白白消耗。一般设 5 分钟足够了。

3. 打卡脚本的核心逻辑拆解

3.1 从浏览器操作到 HTTP 请求的转换

手动打卡的过程,本质上就是浏览器向服务器发送了一系列 HTTP 请求。我们要做的,就是用代码模拟这些请求。关键在于搞清楚三件事:请求发到哪个地址、带了什么参数、需要什么身份凭证。

获取这些信息最直接的方法是打开浏览器的开发者工具。按 F12,切到 Network 面板,然后手动完成一次打卡操作。你会看到一串请求记录,找到那个提交打卡数据的请求(通常是 POST 方法),点进去看它的 Request URL、Request Headers 和 Request Payload。

这里有几个关键信息需要提取:

  • Request URL:打卡接口的完整地址
  • Request Method:通常是 POST
  • Content-Type:一般是application/json或application/x-www-form-urlencoded
  • Request Payload:提交的具体数据,比如体温、位置、健康状况等
  • Cookie 或 Authorization:身份凭证,这是最关键也最容易过期的东西

我建议把这次请求完整地复制为 cURL 命令(开发者工具里右键就有这个选项),然后拿这个 cURL 命令去逐步转换成 Python 或 JavaScript 代码。这样比对着面板一个个抄要准确得多。

3.2 身份凭证的获取与保活策略

身份凭证是整个方案里最脆弱的一环。大部分平台的登录态都是通过 Cookie 或 Token 维持的,而这些凭证通常有有效期。短的可能几小时,长的可能几天到几周。

我的处理策略是这样的:

第一步,先确认凭证的有效期。手动登录一次,把 Cookie 复制出来,然后隔一段时间用这个 Cookie 发请求,看什么时候开始返回未登录状态。这个测试能帮你判断需要多久更新一次凭证。

第二步,把凭证存到 GitHub Secrets 里。绝对不要把 Cookie 或 Token 直接写在代码里然后提交到仓库,哪怕是私有仓库也不安全。GitHub 提供了 Secrets 功能,在仓库的 Settings → Secrets and variables → Actions 里添加,然后在 workflow 里通过${{ secrets.XXX }}引用。

第三步,设置失效通知。在脚本里加一个判断:如果请求返回的是未登录状态,就触发一个失败通知。这样你就能及时知道凭证过期了,需要手动更新。

import os import requests cookie = os.environ.get('CHECKIN_COOKIE') headers = { 'Cookie': cookie, 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Content-Type': 'application/json' } resp = requests.post('https://example.com/api/checkin', headers=headers, json={ 'temperature': '36.5', 'health': 'normal' }) if resp.status_code == 200 and 'success' in resp.text: print('打卡成功') else: print('打卡失败,请检查凭证') exit(1) # 非零退出码会让 Action 标记为失败,触发通知

这段代码里,exit(1)很关键。GitHub Actions 通过退出码判断步骤是否成功,非零退出码会触发失败通知,这样你就能第一时间知道出问题了。

3.3 请求参数的构造与常见陷阱

构造请求参数看起来简单,但实际操作中有几个容易翻车的地方。

时间戳和签名的处理。有些平台会在请求里带一个时间戳或者签名参数,这个值是根据当前时间动态计算的。如果你直接复制之前的请求参数,时间戳对不上,服务器就会拒绝。遇到这种情况,你需要找到签名的计算逻辑,通常是在某个 JavaScript 文件里,把它逆向出来用代码实现。

必填字段的遗漏。手动操作时,浏览器会自动带上一些你看不见的字段,比如_csrf、token、sessionId之类的。复制 cURL 命令的时候要仔细检查,确保所有字段都带上了。

编码问题。如果请求体里有中文,要注意编码格式。application/json默认是 UTF-8,但application/x-www-form-urlencoded可能需要额外处理。我遇到过因为中文姓名编码不对导致打卡失败的情况,排查了半天才发现是编码问题。

重定向处理。有些接口会返回 302 重定向,requests库默认会自动跟随重定向,但有时候重定向后的请求会丢失 Cookie 或 Header。如果发现请求返回 200 但数据不对,可以试试设置allow_redirects=False手动处理。

4. 把脚本搬进 GitHub Actions 的完整流程

4.1 仓库结构与 workflow 文件编写

一个典型的打卡自动化仓库结构是这样的:

checkin-bot/ ├── .github/ │ └── workflows/ │ └── daily-checkin.yml ├── checkin.py ├── requirements.txt └── README.md

daily-checkin.yml是核心配置文件,定义了什么时候跑、跑什么、怎么跑。下面是一个完整的示例:

name: Daily Checkin on: schedule: # 每天 UTC 23:00 触发,对应北京时间 7:00 - cron: '0 23 * * *' workflow_dispatch: # 支持手动触发,方便调试 jobs: checkin: runs-on: ubuntu-latest timeout-minutes: 5 steps: - name: 检出代码 uses: actions/checkout@v4 - name: 设置 Python 环境 uses: actions/setup-python@v5 with: python-version: '3.11' - name: 安装依赖 run: pip install -r requirements.txt - name: 执行打卡 env: CHECKIN_COOKIE: ${{ secrets.CHECKIN_COOKIE }} NOTIFY_URL: ${{ secrets.NOTIFY_URL }} run: python checkin.py

这个配置里,workflow_dispatch是我强烈建议加上的。它允许你在 GitHub 网页上手动点击运行,调试的时候非常方便,不用等到第二天定时触发才能看结果。

4.2 Secrets 配置与敏感信息隔离

Secrets 的配置路径是:仓库页面 → Settings → Secrets and variables → Actions → New repository secret。添加之后,在 workflow 里通过${{ secrets.名称 }}引用。

有几个细节需要注意:

  • Secret 名称只能包含字母、数字和下划线,不能以数字开头
  • Secret 的值一旦保存就无法再查看,只能重新设置
  • Secret 在日志里会被自动打码,但如果你的脚本把 Secret 打印到了非标准输出,可能会泄露
  • 在if条件里不能直接使用 Secrets,需要先通过env传递

我一般会把所有敏感信息都放进 Secrets:Cookie、Token、通知服务的 Webhook 地址、邮箱密码等。代码里只通过环境变量读取,这样即使仓库不小心变成公开的,也不会泄露凭证。

4.3 通知机制的接入方式

打卡成功与否,你得知道结果。GitHub Actions 本身在失败时会发邮件通知,但邮件容易被忽略,而且成功时不会通知。我建议接入一个更及时的通知渠道。

常见的通知方式有几种:

Server 酱。国内用得比较多,通过一个 Webhook 地址发送消息到微信。配置简单,免费额度够个人使用。

Bark。iOS 用户的首选,推送到 iPhone 的通知中心,实时性很好。

Telegram Bot。如果你用 Telegram,可以创建一个 Bot,通过 Bot API 发送消息。免费且稳定。

邮件通知。用 Python 的smtplib发送邮件,适合不想依赖第三方服务的人。

以 Server 酱为例,在脚本末尾加上这样的代码:

import os import requests def notify(title, content): url = os.environ.get('NOTIFY_URL') if url: requests.post(url, json={ 'title': title, 'content': content }) # 打卡成功后调用 notify('打卡成功', '今日打卡已完成')

这样每天打卡完成后,你会在微信里收到一条消息,心里踏实。

5. 调试与排错:那些我踩过的坑

5.1 本地能跑但 Action 里失败的原因排查

这是最常见的问题:在本地电脑上跑得好好的脚本,放到 GitHub Actions 里就报错。原因通常有这几类:

环境差异。本地是 Windows,Action 里是 Ubuntu,路径分隔符、换行符、默认编码都可能不一样。解决办法是在本地也用 Docker 跑一个 Ubuntu 环境测试,或者直接在 Action 里加调试输出。

依赖版本不一致。本地装的requests是 2.31,Action 里装的是最新版 2.32,某些 API 可能有变化。解决办法是在requirements.txt里锁定版本号,比如requests==2.31.0。

网络环境差异。本地能访问的某些地址,在 GitHub 的服务器上可能访问不了,或者需要额外的代理配置。这个只能通过日志排查,看具体卡在哪一步。

时区问题。本地是北京时间,Action 里默认是 UTC。如果脚本里有跟时间相关的逻辑,比如判断今天是不是工作日,就可能出错。解决办法是在脚本开头设置时区:

import os os.environ['TZ'] = 'Asia/Shanghai'

5.2 定时任务不触发或延迟的应对

前面提到过,GitHub Actions 的定时任务不保证精确。我遇到过几次延迟超过 30 分钟的情况,也遇到过偶尔完全不触发的情况。

应对策略有几个:

设置多个触发时间点。比如你想在 7 点打卡,可以设置 6:30、7:00、7:30 三个触发时间,脚本里加一个判断:如果今天已经打卡成功过,就直接退出。这样即使某个时间点延迟或没触发,还有其他机会。

用外部服务做兜底。如果打卡非常重要,可以考虑用一个免费的监控服务(比如 UptimeRobot)定时访问你的 Action 触发接口。不过 GitHub 没有直接提供 HTTP 触发 Action 的接口,需要绕一下,用repository_dispatch事件配合一个中间服务来实现。

接受不完美。说实话,大部分打卡场景对时间的容忍度还是比较高的,延迟十几分钟通常没问题。如果实在要求精确到分钟,那 GitHub Actions 可能不是最佳选择,需要考虑云服务器方案。

5.3 凭证过期导致失败的预警设计

凭证过期是必然会发生的,关键是要在它发生时第一时间知道,而不是等到被提醒才发现。

我的做法是在脚本里加一个"凭证有效性检查"步骤,放在打卡之前:

# 先检查凭证是否有效 check_resp = requests.get('https://example.com/api/user/info', headers=headers) if check_resp.status_code == 401 or 'login' in check_resp.url: notify('凭证已过期', '请及时更新 CHECKIN_COOKIE') exit(1)

这样一旦凭证失效,你会立刻收到通知,有时间去手动更新。更新之后,在 GitHub 上手动触发一次 Action 验证,确认没问题就行了。

另外,我建议在 README 里记录凭证的更新日期和预计有效期,这样心里有个数,可以提前准备。

6. 扩展思路:从打卡到更广泛的自动化

6.1 多平台签到的统一管理

如果你有多个平台需要每日签到,没必要每个都建一个仓库。可以在一个仓库里放多个脚本,用一个 workflow 依次执行,或者用 matrix 策略并行执行。

jobs: checkin: runs-on: ubuntu-latest strategy: matrix: task: [platform_a, platform_b, platform_c] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: '3.11' - run: pip install -r requirements.txt - run: python checkin_${{ matrix.task }}.py env: COOKIE: ${{ secrets[format('{0}_COOKIE', matrix.task)] }}

这样三个平台会并行执行,互不影响,而且日志分开,排查问题很方便。

6.2 用 Actions 做更多定时任务

打卡只是冰山一角。GitHub Actions 的定时能力可以用在很多地方:

  • 每天定时抓取某个网站的数据,存到仓库里做趋势分析
  • 定时检查某个商品的价格,降价时发通知
  • 定时备份某个 API 的数据到 GitHub 仓库
  • 定时运行测试套件,监控服务可用性
  • 定时生成日报、周报并发送

核心思路是一样的:把重复的、有规律的操作写成脚本,用 cron 触发,用通知反馈结果。掌握了这个模式,你能自动化的东西远超想象。

6.3 安全边界与合规使用的个人体会

最后聊几句实在的。自动化工具本身是中性的,但使用的时候要注意边界。

第一,不要高频请求。每天一次、两次没问题,但如果设置成每分钟跑一次,那就是在给服务器添堵,也可能触发风控。合理使用,利人利己。

第二,不要分享凭证。你的 Cookie 和 Token 就是你的身份,泄露出去别人就能冒充你操作。Secrets 功能要用好,不要图省事直接写在代码里。

第三,关注平台规则。有些平台明确允许自动化签到,有些则不允许。使用前花两分钟看看用户协议,避免不必要的麻烦。

第四,做好失效准备。任何自动化方案都可能因为平台改版而失效。脚本报错的时候不要慌,按本文的排查思路一步步来,大部分问题都能解决。

我自己用这套方案跑了很长时间,中间经历过接口变更、凭证过期、Action 延迟等各种情况,但整体来说,它帮我省下的时间和精力远远超过维护成本。每天早上不再需要惦记打卡这件事,那种感觉还是很爽的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询