Skip to content

About

羽毛球场地自动预约 — 三种抢场方式(Safari DOM 自动化 / 逆向 API 直连 / Android App),支持 CAS 认证、智能策略、冲突处理和钉钉通知。

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

羽毛球场地预约 🏸

自动预约大学体育场馆羽毛球场地,提供 3 种抢场方式,适应不同场景和平台。

Python Kotlin Platform

📋 三种抢场方式对比

方式 平台 原理 速度 适用场景
Safari 自动点击 macOS AppleScript 控制 Safari + JS 注入点击页面 DOM 中等 无需逆向 API,所见即所得
API 直连 macOS / Windows 逆向 API + Playwright CAS 登录 → 直接 HTTP 请求 最快 追求极致速度,可跨平台
Android App Android 同上 API + WebView CAS 登录 → OkHttp 请求 快 移动端,随时随地抢场

✨ 核心特性

  • ⚡ 毫秒级抢场 —— API 直连模式绕过浏览器,直接 HTTP 请求,~200ms 响应
  • 🧠 智能选场策略 —— 多维度优先级评分(不靠墙优先 / 靠墙保底),Top-N 备选 + 冲突自动切换
  • 🔄 候补轮询 —— 循环查场,目标时间段一有空场立即下手
  • ⏰ 定时启动 —— 提前运行,到预设放场时间自动开始
  • 📢 钉钉通知 —— 实时推送抢场状态(启动、无场、冲突、成功),支持 HMAC 加签
  • 🎛️ Web 图形界面 —— 浏览器端可视化配置所有参数,一键保存并启动
  • 🔑 自动登录 —— Playwright / WebView 完成 CAS 统一认证,Token 缓存 5 小时
  • 🔐 请求签名 —— 完整还原前端签名算法(MD5),无惧接口加密

1. Safari 自动点击 (macOS)

通过 AppleScript 控制 Safari 浏览器,注入 JavaScript 读取 Vue 渲染后的 DOM,解析场地时间格,自动点击完成预约。

依赖

  • macOS + Safari
  • Safari 菜单「开发」→ 勾选「允许 Apple 事件中的 JavaScript」
  • Python 3.9+

安装

cd safari_booking
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

核心命令

cd safari_booking && source .venv/bin/activate

# 查看当前可订场地(不自动点击)
python3 scripts/check_court_availability.py

# 查看 + 自动点击预约
python3 scripts/check_court_availability.py --click

# 详细诊断模式(抢场失败时打印更多信息)
python3 scripts/check_court_availability.py --click -v

# 保存 HTML 快照(不解析)
python3 scripts/check_court_availability.py --save-only

也可以从项目根目录通过 config_ui.py 一键启动(含自动登录):

python3 config_ui.py
# 在浏览器中配置参数后,点击「保存并启动抢场 (Safari)」

### 候补模式

在目标时间窗口内循环刷新检测,一旦有空场立即抢:

```bash
cd safari_booking && source .venv/bin/activate
python3 scripts/standby_court.py
python3 scripts/standby_court.py --start 19:00 --end 22:00
python3 scripts/standby_court.py -v --no-refresh --max-rounds 50

配置(修改脚本顶部常量)

参数 说明 默认值
PLAY_WINDOW_START / _END 偏好时间窗口 19:00 ~ 20:00
WALL_COURT_NUMBERS 靠墙场地编号列表 见脚本
WAIT_UNTIL_ENABLED 是否等到指定时刻再执行 True
WAIT_UNTIL_CLOCK 目标执行时间 16:00
REFRESH_DATE_BUTTON_INDEX 刷新时选第几个日期(1=今天, 2=明天) 2

工作流程

Safari 标签页(Vue SPA)
  → AppleScript do JavaScript → 抓取渲染后 DOM HTML
  → BeautifulSoup 解析 div.sites-item → CourtFree 数据类
  → decide_booking() 选择最佳方案:
      窗口 ≥2h:偏好连续两小时
      否则:最优单小时
      平局规则:不靠墙 > 靠墙,低场地号 > 高场地号,早开始 > 晚开始
  → (--click) JS 注入点击时间格 → 点击「预约」按钮 → 确认弹窗

2. API 直连(跨平台)

逆向场馆预约系统的后端 API,直接用 HTTP 请求完成登录、查场、预约,比浏览器操作快得多。

安装

cd api_reverse
python3 -m venv .venv
source .venv/bin/activate
pip install -r scripts/requirements.txt
pip install playwright
playwright install chromium

配置凭据

项目根目录下创建 credentials.json(已加入 .gitignore):

{
    "username": "你的学号",
    "password": "你的密码"
}

核心命令

# 图形配置界面(浏览器打开,可视化设置所有参数)
# 从项目根目录运行(无需 venv)
python3 config_ui.py

# 命令行直接启动
cd api_reverse && source .venv/bin/activate
python3 scripts/e2e_test.py

# 候补模式(定时轮询,有空即抢)
python3 scripts/api_standby.py --interval 10

配置界面

config_ui.py 在浏览器中打开配置页面,支持:

  • 定时等待:设定抢场时刻(如 16:00),程序到点自动启动
  • 时间窗口:偏好开始/结束时间
  • 日期:今天 / 明天
  • 优先级模式:quality(不靠墙优先)/ guarantee(靠墙保底)
  • 靠墙场地等级:W1 ~ W4 分级

抢场流程

Playwright 打开 Chromium → CAS 统一认证登录
  → 缓存 token(5 小时有效)
  → API 查场地(~200ms)
  → 生成 Top-N 备选列表(按偏好排序)
  → 逐个尝试预约(遇冲突自动切换下一个备选)
  → 成功 / 全部失败

冲突处理

错误码 含义 自动处理
1610001 服务端限流 同场地重试最多 5 次
40100068 预约人数过多 同场地重试
40100077 已被他人抢占 立即切换下一个备选

3. Android App

Kotlin + Jetpack Compose 原生 Android 应用,与 API 直连方案共享同一套后端接口,通过 WebView 完成 CAS 登录后在手机上完成抢场。

技术栈

  • 语言:Kotlin 1.9
  • UI:Jetpack Compose + Material 3
  • 网络:OkHttp 4 + Gson
  • 架构:MVVM(ViewModel + StateFlow)
  • 最低 SDK:26 (Android 8.0)

功能

  • SharedWebView:共享一个 WebView 实例完成 CAS 登录,登录状态跨页面复用
  • Token 缓存:自动缓存认证 token,过期自动重新登录
  • 可视化抢场:场地网格、进度条、呼吸动画、烟花庆祝效果
  • 通知提醒:抢场结果通过系统通知即时推送
  • 配置界面:图形化设置所有抢场参数
  • 过期机制:编译时设定过期日期

构建

用 Android Studio 打开 android_app/ 目录,Sync Gradle 后直接 Run。

项目结构

android_app/app/src/main/java/com/badminton/booking/
├── MainActivity.kt           # 入口 Activity,过期检查
├── BadmintonApp.kt           # Application 类
├── SharedWebView.kt          # 全局共享 WebView(CAS 登录复用)
├── api/
│   └── BookingClient.kt      # API 客户端(查场、预约、支付)
├── auth/
│   ├── AuthManager.kt        # 认证管理(Token、Cookie)
│   └── TokenCache.kt         # Token 持久化缓存
├── config/
│   └── AppConfig.kt          # 应用配置
├── notify/
│   └── NotificationHelper.kt # 系统通知
├── ui/
│   ├── screen/               # 页面(Login、Config、Booking 等)
│   └── theme/                # Material 3 主题
└── viewmodel/
    └── AppViewModel.kt       # 状态管理

🔔 钉钉通知(三种方式通用)

设置环境变量后,抢场启动、运行状态、成功/失败结果均自动推送至钉钉群:

export DINGTALK_WEBHOOK='https://oapi.dingtalk.com/robot/send?access_token=...'
export DINGTALK_SECRET='SEC...'  # 可选,若机器人开启了加签

未设置 Webhook 则仅终端输出,不影响程序运行。


🗂 项目目录总览

.
├── config_ui.py                   # 抢场配置界面(浏览器,统一入口)
├── dingtalk_notify.py             # 钉钉通知模块(共享)
├── config.json                    # 抢场参数(由 config_ui 写入)
├── credentials.json               # 登录凭据(需自行创建,不提交)
│
├── safari_booking/                # Safari 自动点击方案
│   ├── .venv/
│   ├── scripts/
│   │   ├── check_court_availability.py  # Safari 自动点击主脚本
│   │   ├── launcher.py                  # Safari 自动登录启动器
│   │   ├── standby_court.py             # Safari 候补模式
│   │   └── standby_ui.py                # 候补配置界面(浏览器)
│   └── snapshots/                 # 调试 HTML 快照
│
├── api_reverse/                   # API 逆向 + 直连方案
│   ├── .venv/
│   ├── scripts/
│   │   ├── e2e_test.py            # API 抢场主程序
│   │   ├── api_standby.py         # API 候补程序
│   │   ├── booking_client.py      # API 客户端
│   │   ├── playwright_login.py    # Playwright CAS 登录
│   │   ├── cas_auth.py            # CAS 认证
│   │   └── sign.py                # 接口签名算法
│   ├── docs/                      # API 逆向文档
│   ├── har/                       # HTTP Archive 抓包记录
│   └── js_source/                 # 前端 JS 源码(逆向参考)
│
├── android_app/                   # Android App
│
├── mobile_app/                    # Mobile App(开发中)
│
└── docs/                          # 文档

⚠️ 注意事项

  • 凭据安全:credentials.json、.env、LoginScreen.kt 等包含敏感信息,已加入 .gitignore,请勿提交到仓库
  • Token 有效期:API 方案中登录 Token 约 5 小时过期,程序会自动重新登录
  • 代理:如果系统开着 ClashX,API 方案会自动使用 127.0.0.1:7890;校园网环境直连即可
  • 合法使用:本工具仅供个人合理使用,请遵守场馆管理规定

📄 License

MIT License — 仅供个人学习研究使用。

About

羽毛球场地自动预约 — 三种抢场方式(Safari DOM 自动化 / 逆向 API 直连 / Android App),支持 CAS 认证、智能策略、冲突处理和钉钉通知。

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages