# buy_script **Repository Path**: debuger123/buy_script ## Basic Information - **Project Name**: buy_script - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-18 - **Last Updated**: 2026-04-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # GLM Coding Plan Lite 抢购脚本 — 技术文档 > 项目地址:桌面 `glm_lite_buy/` > 创建日期:2026-04-18 --- ## 一、背景 GLM Coding Plan Lite 套餐每天 10:00 开售,因抢购人数众多,10:00 整页面无法正常加载(服务器过载/白屏/500 错误),导致手动购买几乎不可能成功。 本项目的目标:**绕过前端页面,直接通过 API 完成购买,同时解决验证码问题。** --- ## 二、逆向分析 ### 2.1 分析目标 ``` https://bigmodel.cn/glm-coding ``` ### 2.2 分析方法 1. **抓取页面 HTML** → 提取 JS 文件引用路径 2. **下载 JS Bundle** → 搜索 `subscribe`、`pay`、`purchase`、`preview` 等关键词 3. **提取 API 端点** → 还原完整的购买流程 4. **提取产品配置** → 获取所有套餐的 productId 和价格 ### 2.3 发现的 Token 存储位置 | 存储 | key | 说明 | |------|-----|------| | Cookie | `bigmodel_token_production` | JWT 格式的认证 Token | | LocalStorage | `user` | 用户信息 JSON(含 customerNumber) | Token 值格式为 JWT(`eyJhbGci...`),解码后包含: ```json { "user_type": "PERSONAL", "user_id": 750536, "customer_id": "28641726227913190", "username": "zbucfosd" } ``` ### 2.4 验证码机制 - 类型:腾讯防水墙(TencentCaptcha) - AppId:`196026326` - SDK:`https://turing.captcha.gtimg.com/turing.js` - 回调返回:`{ ticket, randstr }` ### 2.5 API 测试结论 | 测试 | 结果 | |------|------| | `/biz/pay/check` 不带验证码 | ✅ 可用 | | `/biz/pay/preview` 不带验证码 | ❌ 返回 `code: 500, msg: "请完成安全验证"` | | `/biz/pay/preview` 带验证码 | ✅ 可用(需浏览器环境) | **结论:纯 Python requests 方案不可行,必须在浏览器中处理验证码。** --- ## 三、方案选型 ### 3.1 方案对比 | 方案 | 优点 | 缺点 | 结论 | |------|------|------|------| | 纯 API (Python requests) | 最快,无依赖 | 过不了验证码 | ❌ 不可行 | | 页面自动化 (点按钮) | 简单直接 | 10 点页面卡死就废了 | ❌ 不可行 | | Playwright + API 直调 | 不依赖页面 UI,能过验证码 | 需安装 Playwright | ✅ 采用 | | 半自动监控 | 实现简单 | 页面打不开没用 | ❌ 不可行 | ### 3.2 最终方案:Playwright + 浏览器内 fetch ``` Playwright 浏览器(容器) ├── 页面 UI(不依赖,卡死无所谓) ├── Cookie(自动管理,不需要手动复制 token) ├── JS 上下文(通过 page.evaluate 执行) │ ├── fetch() → 直调后端 API │ └── TencentCaptcha → 触发验证码弹窗 └── 用户交互 → 手动完成验证码(2-3 秒) ``` **核心思路:浏览器只是保住 cookie 会话的容器,所有购买逻辑通过 JS 上下文中的 fetch() 完成,不依赖页面 UI。** --- ## 四、项目文件结构 ``` glm_lite_buy/ ├── playwright_buy.py ← 主脚本(Playwright 版,推荐使用) ├── glm_lite_buy.py ← 备用脚本(纯 API 版,需手动填 token,可能过不了验证码) ├── captcha_helper.html ← 验证码获取辅助页(备用) ├── test_captcha.py ← 测试脚本:验证 preview 是否需要验证码 ├── find_token.js ← 浏览器 Console 脚本:搜索 token 位置 └── README.md ← 本文档 ``` --- ## 五、主脚本设计(playwright_buy.py) ### 5.1 运行方式 ```bash pip install playwright python -m playwright install chromium python glm_lite_buy/playwright_buy.py ``` ### 5.2 配置项 ```python PRODUCT_ID = "product-02434c" # Lite 月付 ¥49 # PRODUCT_ID = "product-b8ea38" # Lite 季付(9折) ¥132.3 TARGET_HOUR = 10 # 抢购时间 - 小时 TARGET_MINUTE = 0 # 抢购时间 - 分钟 PAYMENT = "WE_CHAT" # "WE_CHAT" 或 "ALI" ``` ### 5.3 四个阶段 #### 阶段一:初始化(随时,建议提前运行) > **重要:不要等到 9:58 才运行!** 9:58 系统可能已经限流,页面无法加载、登录接口也可能被封锁。 > 建议在 9:00 甚至更早运行脚本,在系统空闲时完成登录,脚本会全程保活到 10:00。 ``` 随时启动脚本 → 打开 Chromium → 加载 glm-coding 页面 ↓ 检测登录状态(未登录则等待用户手动登录) ↓ 注入 __glmBuy 辅助函数到 JS 上下文 ↓ 验证 token 有效 → 读取 customerId ``` **设计思路:将"登录"和"抢购"解耦** | | 登录 | 抢购 | |--|------|------| | 时间 | 任意时间(系统空闲) | 10:00 整 | | 依赖 | 页面能正常打开 | 只需 API 可达 | | 限流风险 | 提前登录,无风险 | 无法避免 | 注入的辅助函数: ```javascript window.__glmBuy = { api(method, path, body) // 封装 fetch,自动带 cookie doCaptcha() // 触发腾讯防水墙,动态加载 SDK getCustomerId() // 从 localStorage 读取 customerNumber } ``` #### 阶段二:全程保活等待(初始化完成 → 10:00) ```python while datetime.now() < target: result = api_call(page, "GET", "/biz/pay/check?bizId=...") if result.code == 401: # Token 过期, 提醒用户重新登录 alert() input("登录后按回车继续...") if remaining < 30: time.sleep(1) # 最后 30 秒: 每秒心跳 else: time.sleep(20) # 正常: 每 20 秒心跳 ``` - **全程保活**:从登录完成到 10:00,每 20 秒调一次 `check` API,防止 cookie 过期 - **Token 过期自动检测**:保活请求返回 401 时响铃提醒用户重新登录 - **最后 30 秒加速**:心跳频率从 20 秒提升到 1 秒,确保进入 10:00 时会话绝对有效 - 不依赖页面 UI,页面白屏不影响保活 #### 阶段三:抢购(10:00) ``` 循环尝试 (最多 150 次): │ ├── check → 检查是否可购买 │ ├── preview (不带验证码) ──→ 成功 → 跳到 create-sign │ │ │ └── 返回"需要验证" ──→ 触发 TencentCaptcha 弹窗 │ │ │ ├── 确保 SDK 已加载(动态注入 turing.js) │ ├── 弹出验证码,等待用户手动完成 │ ├── 拿到 ticket + randstr │ └── 带 ticket 重试 preview → 成功 │ ├── create-sign → 创建支付订单 │ └── 成功 → 响铃 + 自动打开支付页面 ``` #### 阶段四:异常恢复 | 异常 | 处理 | |------|------| | `page.evaluate()` 失败 | 先重试,连续失败则重载页面 + 重新注入辅助函数 | | Token 过期 (code=401) | 响铃提示,等待用户重新登录后按回车继续 | | SDK 未加载 | `doCaptcha()` 内自动动态创建 `