Always a step too slow? Maybe it's time to let the script run.

注意:由于对滥用防范和系统安全的考虑,该项目目前暂未开源,仅为个人测试与学习使用。


这个项目是一个面向西浦体育中心预约流程的自动化脚本,会把登录、验证码识别、动态码验证、到点切页、选场提交和可选支付这些步骤按顺序执行。
整个流程会优先复用已有登录态,如果失效就自动进入验证码和逆向 OTP 登录,在检测登录状态正确后,按配置文件进行下一步提交订单和付款操作。

README_zh.md

西浦体育中心自动订场脚本

这是一个用于西浦体育中心官网订场的自动化脚本。

仅供个人测试与学习使用。


快速使用

  1. 配置 pe.config.json
  2. 参考 pe.config.json.example 填写配置。
  3. 运行 run-pe.bat
  4. 脚本会打开浏览器、检查登录状态、等待到设定时间,并通过先切壁球页再切回目标场地页的方式进入抢场流程。
  5. 提交订单后,浏览器会保持打开,直到你手动关闭。

登录方式

login.mode 支持:

  • manual:总是手动登录
  • storage_state:优先复用已保存登录态,失败后回退到手动登录
  • otp:通过二维码载荷生成动态码并自动登录

相关配置项:

  • login.saveStorageStateAfterLogin
  • login.captcha.enabled
  • login.captcha.expectedLength
  • login.captcha.maxAttempts
  • login.otp.sportsCenter
  • login.otp.minSecondsRemaining
  • login.otp.qrPayloadBase64

当登录框中出现图片数字验证码时,脚本会在 OTP 登录前自动截图验证码图片,使用本地 OCR 识别,并在识别失败时自动刷新验证码后重试。

当前验证码逻辑还包括这些细节:

  • login.captcha.expectedLength 会被严格用于判断 OCR 结果位数;位数不匹配时会直接刷新验证码并进入下一次 OCR 尝试
  • 如果网页提示 验证码错误,请重新输入。,脚本会把它视为验证码识别失败,只刷新验证码并重试,而不是立刻结束整轮 OTP 登录
  • OTP 会在验证码识别完成、真正点击登录前再生成一次,以减少验证码处理耗时导致 OTP 过期的概率

浏览器配置

  • browser.mode:可选 autolocalplaywrightcustom
  • auto:优先本机 Chrome / Edge,找不到再回退到 Playwright 浏览器
  • local:强制使用本机 Chrome / Edge
  • playwright:强制使用 npx playwright install chromium 安装的浏览器
  • custom:使用 browser.executablePath 指定路径

自动支付逻辑

  • payment.autoPay:是否在提交订单后继续自动进入支付流程

payment.autoPaytrue 时,脚本会:

  1. 等待支付页加载完成。
  2. 定位优惠券区域和支付汇总区域。
  3. 如果最左侧优惠券还没被选中,就自动点选它。
  4. 读取并打印当前应付金额信息。
  5. 点击最终支付确认按钮。
  6. 然后保持浏览器打开,等你手动关闭。

payment.autoPayfalse 时,脚本会:

  1. 只提交订单。
  2. 不自动继续支付。
  3. 由你手动完成支付。
  4. 浏览器同样会保持打开,等你手动关闭。

在测试模式下,脚本还会额外询问:

  • 是否真的提交订单
  • 提交后是否自动支付

所以测试模式下可以单独验证“提交”和“自动支付”这两个步骤。


Booking 配置说明

现在预约参数支持“配置优先,缺失时再回退终端输入”。

也就是说,如果你在 pe.config.json 里填了 booking,脚本会优先使用配置;如果某个字段没填,才会在运行时再问你。

booking 支持这些字段:

  • booking.dateTarget
  • booking.courtPriority
  • booking.startHour
  • booking.waitUntil
  • booking.bookTwoSlots

booking.dateTarget

支持三种写法:

  • 周几数字,例如 17
  • 固定日期 MM/DD,例如 03/26
  • 特殊值 next7d,表示“当前日期往后 7 天”

booking.courtPriority

支持两种写法:

  • 字符串,例如 "1,2,4"
  • 数组,例如 ["1", "2", "4"]

脚本会按你给出的顺序依次尝试场地。

booking.startHour

只写开始小时,例如:

  • 18

脚本会把它当作 18:00;如果开启连续两小时,则第二个时段会自动按 19:00 处理。

booking.waitUntil

格式:

  • HH:mm:ss

例如:

  • 17:42:40

booking.bookTwoSlots

  • true:尝试连续抢两个时段
  • false:只抢一个时段

运行时提示

在真正开始等待前,脚本会打印一条预约摘要,例如:

Booking target: date=03/26, time=18:00, 19:00, courts=1号场, 2号场, 4号场

这样可以帮助使用者在等待前确认:

  • 日期是否正确
  • 时间是否正确
  • 场地优先级是否正确

其他说明

  • 提交订单后脚本不会自动退出,而是等待你手动关闭浏览器。
  • 如果抢场失败,浏览器也会保持打开,方便你观察页面状态。
  • 当前最多支持连续 2 个小时的抢场逻辑。
  • 如果你希望在其他电脑上得到更稳定一致的浏览器行为,建议提前安装 Playwright 浏览器并使用 browser.mode: "playwright"

演示视频: