补退选课程名额监控工具。它在本机 Chrome 中登录选课系统,按设定间隔读取补退选列表;当符合条件的课程出现空余时,发一封邮件提醒。
它只做查询和提醒,不会替你选课,也不会处理验证码。
请只用于自己的账号,并遵守学校的相关规定。登录、查询和翻页之间会保留随机间隔;遇到风控提示或验证码时,程序会停止本轮,而不是继续尝试。
本工具仅用于个人课程选课状态的查询与提醒,不保证其正确性、稳定性或可用性。使用者应自行承担使用本工具带来的一切风险与后果;作者对因使用 courser 导致的任何直接或间接后果概不负责。
请合理设置并适当放大操作间隔(如 interval_min、page_delay_min/max 等),保持接近正常人类的操作节奏;不要用本工具进行任何批量、高频或违反规定的操作。
# 从 PyPI 安装(只带 rich/textual;opencli/gws 需另装,见下方)
pipx install courser # 推荐:独立 CLI 环境,不污染系统 Python
# 或装入当前 Python 环境:
pip install courser# 更新
pipx upgrade courser # 推荐(pipx 安装时用这个)
pip install --upgrade courser # 或:pip install -U courser
uv tool upgrade courser # 若当初用 uv tool install发布到 PyPI 只包含 courser 自身与
rich/textual两个 Python 依赖。 opencli / gws 不随包发布,需在本机单独安装(见下方 Quick start 的说明)。
需要:Python 3.12+、uv、Chrome,以及两个已完成配置的命令行工具:
- OpenCLI:连接本机 Chrome。安装扩展、启动 daemon 后,运行
opencli doctor,确认检查通过。 - Google Workspace CLI(
gws):发送提醒邮件。 安装:npm install -g @googleworkspace/cli。 首次先执行gws auth setup(一次性初始化 Google Cloud 项目 / OAuth 配置 / 启用 API), 再执行gws auth login授权 Gmail;之后 token 失效时重新gws auth login即可。 - 注意将自己的账号添加到 Google Auth Platform 的测试用户中,否则可能无法完成
gws的相关配置。
git clone https://github.com/xjsongphy/courser
cd courser
uv sync
uv run courser第一次启动会打开设置向导:填写收件邮箱保存后会自动生成 config.json(无需手动复制),其余设置可在程序的设置页完成。
若你更愿意由 Chrome 或密码管理器填充学号和密码,保持 credentials 为空即可;也可以写入 config.json,或通过环境变量 PKU_USERNAME、PKU_PASSWORD 提供。
- 每轮从 IAAA 登录,打开补退选页面,并按网站实际页数读取课程;不依赖固定页数。
- 按课程名、课程类别和开课院系筛选。可选择任一条件命中或全部条件命中。
- 只有“限数大于已选”的课程才会提醒;同一门课有冷却时间,邮件也有每小时上限。
- 提供一个终端界面查看最近结果、调整筛选和设置、查看日志。文字选择风格为 Textual 自接管:鼠标拖动选择、松手即自动复制到剪贴板(OSC 52),并 toast 提示;滚轮滚 页面,帮助 / 日志 / 详情页均可用。
uv run courser --once这会跑完一轮并把结果打印到终端,适合确认登录和筛选是否正常。持续运行则直接执行 uv run courser。
config.json 会在首次启动向导完成时自动生成,一般情况下无需手动修改——轮询节奏、筛选条件、收件邮箱等都可直接在 TUI 的设置页修改并自动保存。以下为完整的配置结构说明(参考):
config.json 不会提交到 Git。运行日志写入 data/courser.log。
opencli doctor 需要全部通过。若登录页填入账号密码后仍未跳转,先在同一个 Chrome 中手动完成一次登录,再执行 uv run courser --once。验证码和二次验证需要你本人处理,courser 不会代填。
uv run python tests/unit/test_opencli.py
uv run python tests/integration/test_round_runner.py
uv run python tests/tui/test_navigation.py
uv run python tests/tui/test_responsive.py真实网站的端到端检查仍需手动执行:
uv run courser --once
{ "interval_min": 8.0, // 查询间隔(分钟) "interval_jitter": 0.3, // 间隔随机抖动 "page_delay_min": 0.8, // 翻页最小等待(秒,人类节奏) "page_delay_max": 2.0, // 翻页最大等待(秒) "session": "courser-watch", // opencli 浏览器会话名 "window": "background", // 浏览器窗口模式 "force_relogin": true, // 每轮是否强制重新登录 "credentials": { // 可留空(依赖浏览器密码管理器自动填充) "username": "", "password": "" }, "filters": { "names": [], // 课程名,子串匹配 "categories": [], // 课程类别 "depts": ["英语语言文学系"], "match": "any" // any:任一条件命中;all:全部条件命中 }, "notify": { "to": "you@example.com", // 收件邮箱(必填) "gws_from": "", // gws 发件账号(可选,默认取认证账号) "min_interval_min": 15.0, // 同一门课的通知冷却(分钟) "max_per_hour": 5 // 每小时发送上限 } }