Selenium自动化健康打卡实战:从脚本到通用填报框架

发布时间:2026/9/23 11:14:44
Selenium自动化健康打卡实战:从脚本到通用填报框架 简介这是一份面向高校学生与Python自动化爱好者的实战项目源码基于Selenium实现浙江大学自动健康打卡功能适合作为毕业设计、课程设计或自动化脚本学习案例。压缩包共10个文件约6.91MB以py脚本为核心辅以txt说明、yml工作流配置、chromedriver驱动及md文档覆盖打卡主逻辑、验证码识别与消息推送等模块结构清晰便于二次开发。项目为个人高分作品已通过导师指导与答辩评审获95分评价代码经测试可正常运行。已有52人学习下载。读者可从中掌握Selenium元素定位、表单自动填写、定时任务配置及异常处理思路也可在此基础上修改扩展为其他自动化场景适合具备一定Python基础、希望提升实战能力的学习者参考借鉴。1. 从手动填报到脚本代劳这套浙大健康打卡源码到底解决了什么如果你在浙大待过一段时间大概率经历过这样的早晨闹钟响了先摸手机打开打卡页面填体温、选健康状况、勾承诺书、点提交一套动作下来两三分钟偶尔网络卡一下还得重来。单次不累但连续几百天就是折磨。这套基于 Selenium 的自动健康打卡项目核心价值就是把这套重复动作交给浏览器自动化去跑你只需要在配置里填一次账号信息和打卡参数剩下的交给脚本。它适合三类人一是想省事的在校同学二是拿它当 Selenium 实战案例的计算机专业学生三是想在此基础上改造成其他自动化填报任务的开发者。项目里带了完整源码、chromedriver、requirements.txt 和详细文档拿到手就能跑不是那种只给几个片段让你自己拼的半成品。2. 拆开压缩包目录结构与 Selenium 驱动链路2.1 文件清单与各模块职责先把压缩包解开根目录下能看到这些内容AutoClock-main是主工程目录daka.py是打卡主脚本chaojiying.py负责验证码识别DingRobot.py是钉钉机器人通知模块chromedriver是浏览器驱动requirements.txt锁定依赖README.md是使用说明.github/workflows里放了定时任务的配置模板。这个结构说明作者不是随手写了个脚本而是按工程化思路组织的主流程、验证码、通知、依赖、文档各管一摊。daka.py是整个项目的入口它做的事情可以拆成四步启动 Chrome、登录、填写表单、提交并判断结果。chaojiying.py的存在说明打卡页面在某些情况下会弹验证码作者用第三方打码平台来兜底。DingRobot.py则是把打卡结果推送到钉钉群方便你确认今天到底打没打上。这三个文件构成了「执行—识别—反馈」的闭环。2.2 Selenium 驱动链路与 chromedriver 版本匹配Selenium 的工作原理不复杂你的 Python 代码通过 WebDriver 协议跟 chromedriver 通信chromedriver 再去操控真实的 Chrome 浏览器。所以链路上任何一环版本对不上脚本就会在启动浏览器那一步直接翻车。项目里自带了 chromedriver但你要确认它的版本跟你本机 Chrome 的大版本号一致。比如你本机是 Chrome 120驱动也得是 120.x差一个大版本就可能报session not created的错误。# 查看本机 Chrome 版本Windows 在地址栏输入 chrome://version # Linux 下可以用 google-chrome --version # macOS 下 /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --version # 查看项目自带 chromedriver 版本 ./chromedriver --version上面这几条命令的目的很直接把浏览器版本和驱动版本都打印出来做比对。如果版本不匹配去 chromedriver 的官方下载页找对应版本替换掉项目里的那个文件即可。注意 Windows 下驱动文件名是chromedriver.exeLinux 和 macOS 下没有后缀替换时别搞混。2.3 依赖安装与虚拟环境隔离项目根目录的requirements.txt里列了 Selenium、requests 等包。我一般不建议直接往全局 Python 环境里装容易跟其他项目的依赖打架。用 venv 建一个独立环境出问题直接删掉重建比到处找冲突省事得多。# 创建虚拟环境 python -m venv venv # 激活虚拟环境 # Windows: venv\Scripts\activate # macOS / Linux: source venv/bin/activate # 安装依赖 pip install -r requirements.txt # 确认 selenium 版本 pip show seleniumpython -m venv venv会在当前目录下建一个名为 venv 的文件夹里面是一套独立的 Python 解释器和 pip。激活之后你后续所有 pip install 都只影响这个环境。pip show selenium用来确认装上的版本号Selenium 4.x 和 3.x 在 API 上有差异比如 4.x 里find_element_by_id这类写法已经被移除改成了find_element(By.ID, ...)。如果你拿到的代码是 3.x 写法但装的是 4.x运行时会报AttributeError这时候要么降级 Selenium要么把代码里的定位方式改过来。3. 配置与运行把账号、参数和通知串起来3.1 账号信息与打卡参数的配置位置打开daka.py你会看到脚本开头或单独一个配置区域里放着用户名、密码、打卡表单的默认值。常见做法是把这些敏感信息抽到一个单独的配置文件或者环境变量里避免直接硬编码在脚本中。如果项目里没有做这层抽离你可以自己加一个config.py把账号密码放进去然后在daka.py里 import 进来。# config.py 示例 USERNAME 你的学号 PASSWORD 你的密码 # 打卡表单里的默认选项按你实际情况填 DEFAULT_TEMPERATURE 36.5 DEFAULT_LOCATION 校内# daka.py 中引用配置 from config import USERNAME, PASSWORD, DEFAULT_TEMPERATURE # 登录部分大致逻辑 driver.find_element(By.ID, username).send_keys(USERNAME) driver.find_element(By.ID, password).send_keys(PASSWORD) driver.find_element(By.ID, login-btn).click()这里的关键参数是USERNAME和PASSWORD填错的话脚本会在登录页卡住后续所有步骤都走不下去。DEFAULT_TEMPERATURE这类表单默认值要根据学校当时的填报要求来设不同时期字段可能不一样跑之前先手动打开一次打卡页面看看当前要填哪些项再对照着改脚本里的字段定位和默认值。3.2 表单字段定位与显式等待打卡页面上的输入框、下拉框、提交按钮都需要用 Selenium 的定位方法找到。项目里大概率用的是By.ID、By.NAME或By.XPATH。页面加载需要时间如果脚本跑得比页面渲染快就会报NoSuchElementException。解决办法是用显式等待让脚本在找不到元素时先等一会儿再重试。from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 等待提交按钮出现最多等 10 秒 submit_btn WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.ID, submit-btn)) ) submit_btn.click()WebDriverWait(driver, 10)里的 10 是超时秒数意思是最多等 10 秒期间每隔 0.5 秒检查一次条件是否满足。EC.element_to_be_clickable确保元素不仅出现了而且是可以点击的状态。这比用time.sleep(5)硬等要靠谱得多因为硬等要么等不够要么等太久显式等待是条件满足就立刻继续。3.3 验证码识别与钉钉通知的接入chaojiying.py是打码平台的接口封装。如果打卡页面弹了图形验证码脚本会截图验证码区域发给打码平台拿回识别结果再填进去。用这个模块需要你去打码平台注册账号拿到自己的软件 ID 和密钥填到chaojiying.py对应的变量里。不打码平台的话也可以看看验证码是不是简单的算术题或者固定字符如果是直接在脚本里写逻辑判断就行不必额外花钱。DingRobot.py负责把打卡结果推到钉钉。你需要在钉钉群里添加一个自定义机器人拿到 Webhook 地址和加签密钥填到脚本里。打卡成功或失败后脚本会发一条消息到群里你打开手机就能看到今天到底打没打上。这个模块不是必须的但强烈建议配上否则脚本在后台跑你根本不知道它有没有正常工作。# DingRobot.py 中的关键配置 WEBHOOK https://oapi.dingtalk.com/robot/send?access_token你的token SECRET 你的加签密钥 # 发送消息的函数大致长这样 def send_message(content): # 拼接签名、构造请求、发送 ...Webhook 地址和密钥填错的话消息发不出去但打卡本身不受影响。所以如果你发现打卡记录有了但钉钉没收到通知先检查这两个参数再检查网络能不能访问钉钉的接口。4. 避坑与排查那些让你打卡失败的常见问题4.1 驱动版本不匹配导致浏览器起不来现象运行脚本后立刻报错提示session not created: This version of ChromeDriver only supports Chrome version XX。原因是你本机 Chrome 自动更新了但项目里的 chromedriver 还是旧版本。解决方法是查看本机 Chrome 版本去下载对应版本的 chromedriver 替换项目里的文件。如果懒得每次手动换可以用webdriver-manager这个库让它自动下载匹配的驱动。4.2 页面元素定位失效现象脚本能打开浏览器、能登录但到了填表单那一步就报NoSuchElementException。原因是打卡页面的 HTML 结构变了或者字段的 ID、NAME 跟脚本里写的不一样。解决方法是手动打开打卡页面按 F12 打开开发者工具用元素选择器点一下你要填的输入框看看它的 ID 或 NAME 是什么然后改脚本里的定位表达式。如果页面用了 iframe还需要先driver.switch_to.frame()切进去才能找到元素。4.3 登录态过期与会话保持现象昨天还能跑今天一跑就停在登录页提示密码错误或者要求重新登录。原因是学校系统可能改了密码策略或者你的账号在别处登录导致会话失效。解决方法是先手动登录一次确认账号正常然后检查脚本里的密码是不是最新的。如果系统有异地登录检测可能还需要处理额外的验证步骤。4.4 定时任务环境下浏览器无法启动现象在本地跑得好好的放到服务器上用 cron 定时执行就失败。原因是服务器上没有图形界面Chrome 需要以 headless 模式运行。解决方法是在启动 Chrome 的代码里加上options.add_argument(--headless)和options.add_argument(--no-sandbox)。另外 cron 环境下的 PATH 可能跟你的 shell 不一样脚本里最好用绝对路径来指定 chromedriver 的位置。from selenium.webdriver.chrome.options import Options options Options() options.add_argument(--headless) # 无界面模式 options.add_argument(--no-sandbox) # 服务器上常需要 options.add_argument(--disable-dev-shm-usage) # 避免共享内存不足 driver webdriver.Chrome(optionsoptions)这三个参数是无界面环境下的标配。--headless让 Chrome 不弹窗口--no-sandbox解决权限问题--disable-dev-shm-usage避免容器里共享内存太小导致浏览器崩溃。加上之后脚本在服务器上就能安静地跑完。4.5 打卡成功但通知没发出来现象去系统里查记录发现打卡成功了但钉钉群没收到消息。原因是DingRobot.py里的 Webhook 或密钥配错了或者服务器网络访问不了钉钉接口。解决方法是先手动调用一次发送函数看报什么错再检查 Webhook 地址是否完整、加签密钥是否跟机器人设置里的一致。如果服务器在内网可能还需要配置网络出口。5. 进阶改造把打卡脚本变成通用自动化填报框架这套代码跑通之后你会发现它的骨架其实适用于任何「登录—填表—提交」的网页操作。我后来把它改造成了实验室的日报填报工具思路是一样的换掉登录部分的定位表达式换掉表单字段的填写逻辑通知模块原封不动复用。具体做法是抽出一个BaseFormFiller类把打开页面、登录、填字段、提交、通知这几个步骤定义成方法每个具体任务只需要继承这个类并覆盖字段映射就行。class BaseFormFiller: def __init__(self, url, username, password): self.url url self.username username self.password password self.driver self._init_driver() def _init_driver(self): options Options() options.add_argument(--headless) options.add_argument(--no-sandbox) return webdriver.Chrome(optionsoptions) def login(self): raise NotImplementedError def fill_form(self): raise NotImplementedError def submit(self): raise NotImplementedError def notify(self, result): # 复用钉钉通知逻辑 ... def run(self): try: self.driver.get(self.url) self.login() self.fill_form() self.submit() self.notify(打卡成功) except Exception as e: self.notify(f打卡失败{e}) finally: self.driver.quit()这个基类把流程固定下来子类只需要实现login、fill_form、submit三个方法。run方法里用 try-except-finally 保证无论成功失败都会发通知、都会关浏览器。改造的时候你只需要打开目标网页用开发者工具找到各个元素的定位方式填到子类里就行。验证改造是否成功我一般会分两步走先在本地用有界面模式跑一遍肉眼确认每一步都点对了地方再切到 headless 模式跑一遍确认无界面下也没问题。两步都过了再放到定时任务里。从那以后我每次改完定位表达式都会强制走一遍「有界面→无界面→定时任务」这个流程避免直接上服务器然后对着日志猜哪里出了问题。希望这套思路能帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询