项目简介
手动马赛克的网店是出了名的难抢:人气商品常年 SOLD OUT, 补货不定时、量极少,经常上架几分钟就被买空。人肉蹲守不现实,于是写了这个 「自己会买东西」的机器人。
整个流程无人值守:监控进程发现事先在网页上勾选过的商品从售罄变回有货, 就立刻探测限购和库存、按包邮规则组一单,打开浏览器自动完成从登录到点下 「注文する」的全部操作,然后把"买到了没有、为什么"推送到 LINE。人只需要 提前勾选想要什么,以及收到通知后去便利店付款。
系统结构
┌──────────────── 监控进程(Windows,7×24)────────────────┐
│ │
│ 每 2~3 分钟随机间隔抓分类页 ──► 与 state.json 比对 │
│ │ 售罄 → 有货(补货) │
│ ▼ │
│ watchlist.json ◄── 网页勾选界面(购买 / 凑单 双列表) │
│ │ 命中购买列表 │
│ ▼ │
│ 8 线程并行试探限购/在库 ──► 组单:买什么、凑什么、 │
│ │ 够不够包邮、超没超预算 │
│ ▼ │
│ Playwright 驱动本机 Chrome: │
│ 登录 → 清空购物车 → 逐件加购 → 填收货信息 │
│ → 选配送/支付/便利店 → 确认页核对金额 → 下单 │
│ │ 失败则清空购物车恢复干净状态 │
│ ▼ │
│ LINE 推送:补货 Flex 卡片 + 购买结果(成功/失败/原因) │
└──────────────────────────────────────────────────────────┘
▲
手机 / 外网 ── 登录后的勾选界面(局域网或 Cloudflare Tunnel)
几个好玩的点
- 一次请求问出限购和库存:商店没有库存 API,但往购物车提交「100 个」时,
422 响应里会同时带两条带数字的错误(
お一人様N個までです/在庫はN個です), 而且各自有稳定错误码。于是用一次性会话提交一个大数,限购和在库就都有了, 再和自己设的「最多买几个」取最小值。 - 凑包邮算法:商品合计满 16,500 円免运费。购买列表不够线时,自动从「凑单 列表」里按单价从低到高补到线;实在凑不到就看合计是否超过「理想阈值」,超过 就认了运费直接买,否则只通知不买。另有单笔金额上限做安全阀。
- 失败判定从严:没有拿到受注番号或完成页,一律按失败处理——清空购物车恢复 干净状态,把弹窗原文作为失败原因推到 LINE。宁可误报失败,不能假装买到了。
- 通知里带结果:人不在电脑前时,「没买到」比「补货了」更需要立刻知道,所以 LINE 的补货卡片后面永远跟一条文字消息,写明这单的决策和结局。
- 远程勾选:勾选界面是单文件
http.server,无任何 Web 框架。手机通过局域网 或 Cloudflare Tunnel 访问,账号密码登录、同 IP 连错 5 次锁 15 分钟,改完勾选 下一轮监控(2~3 分钟内)自动生效,不用重启。
已实现的功能
- 分类页全量监控:补货 / 上新检测,随机间隔、纯标准库零依赖
- Windows Toast + LINE Flex 图文卡片通知
- 网页勾选界面:购买 / 凑单双列表、数量上限、包邮线实时统计、手机适配
- 限购 / 在库一次试探,8 线程并行
- 凑包邮组单(理想阈值、单笔上限安全阀)
- Playwright 全自动下单:登录态持久化、会员 / 游客结算自适应、失败回滚
- 购买结果随通知推送(成功 / 失败 / 原因 / 便利店付款提醒)
- 一键部署:
一键配置.bat自动装依赖、建基线;纯代码更新包不碰用户数据 - 限购商品「已购清单」:买过的不再反复尝试,限购解除后自动恢复
- 下单失败自动摘掉问题商品重试,不让一件拖垮整单
技术栈
| 部分 | 技术 |
|---|---|
| 监控 / 抓取 | Python 3 标准库(urllib + 正则),无第三方依赖 |
| 勾选界面 | http.server 单文件 Web UI,会话登录 + 失败锁定 |
| 自动下单 | Playwright 驱动本机 Chrome(AngularJS 结算页自动化) |
| 通知 | LINE Messaging API(Flex Message)、Windows Toast |
| 远程访问 | 局域网直连 / Cloudflare Tunnel(免端口转发,自带 HTTPS) |
| 部署 | Windows 双机 7×24,bat 一键配置 + 纯代码增量更新包 |
踩过的坑
- 全新 Windows 的根证书是按需下载的,
certifi没装时 HTTPS 验证随机失败—— 监控有降级回退所以一直正常,探测没有,导致连续十天每次补货都「拟下单 0 件」。 日志完整所以一眼定位,但教训是:同一进程里两套网络栈,容错也要两套都有。 - AngularJS 页面不认自动化工具的合成点击,单选钮必须用原生 DOM
click(); 结算页上的推广浮层和粘性头会挡住一切点击,每步操作前都要先清场。 HTTPServer默认连接队列只有 5,浏览器一次开几十个图片连接时后面的全在排队, 表现就是"远程访问图片时灵时不灵"。队列调大 + 图片直连图床后彻底解决。- cmd 批处理按字节偏移解析文件,UTF-8 中文会让它从行中间接着读、后面每行全碎。
结论:
.bat只写 ASCII,中文提示放外部文本文件用type输出。
这里之后会放勾选界面截图和一次完整抢购的时间线复盘。