JavaDog程序狗
发布于 2026-09-24 / 0 阅读
0
0

【AI】iPhone18抢不到?我用 Codex 做了个苹果库存监控工具

前言

🍊事情起因

最近狗哥盯上了一台 iPhone 18 Pro,512GB、黑色、青岛到店取。

定睛一看,拉倒,没库存。

iPhone 官网显示暂无供应

官网偶尔显示今天可取货,晚一步再看,没了。总不能一天到晚守着页面刷新吧?于是我给 Codex 提了个需求:

帮我盯着苹果官网,只要青岛门店有货就提醒我。

听起来挺简单,看看狗哥如何指挥codex,不用写一行代码,完美实现。

说干就干,不服来战,先看下成果,源码在最下面!!!

苹果库存监控工具运行效果


🎯这次到底要做什么

先别急着写代码,狗哥把想要的效果给 Codex 说清楚:

  1. 页面上能选地区、门店、型号、容量和颜色。
  2. 点一下“保存并监听”,马上查一次库存。
  3. 后面自动盯着,不用我来回刷新官网。
  4. 真有货就响一声,再弹个桌面通知。

看着就四条,真做的时候每条都藏着坑。

接口从哪儿来?哪个字段才代表有货?一次查多少配置合适?查太快被拦了怎么办?浏览器关了还能不能继续?

下面不直接甩最终代码。咱们按当时的排查顺序,一步一步往下走。

正文

🍪第一步:先分析接口,看看库存藏在哪儿

通过开发者工具分析苹果库存接口

苹果官网能显示“今天可取货”,说明浏览器肯定拿到了库存数据。第一步先打开开发者工具,在 Network 里盯住自己切换门店、容量和颜色时发出的请求。

我把抓到的请求和响应丢给 Codex,让它先别写功能,先找出真正决定库存的字段。

购物车页面会请求 bagx,响应里有一段数据很关键:

{
  "partName": "iPhone 18 Pro 256GB 黑色",
  "availabilityQuote": "今天 可取货",
  "availableNowForLine": true
}

Codex 给出的判断很直接:

  • availableNowForLine: true,当前商品可以到店取货。
  • availableNowForLine: false,当前商品不可取货。

到这里看着已经结束了,读一个布尔值就行。

结果页面一跑,32 个配置里只有购物车中的 3 个有结果,另外 29 个全是“未知”。

原因也找到了:bagx 只返回购物车里的商品。没加进购物车的配置,响应里压根没有。

它们到底有货还是没货?不知道。

这里不能图省事,把“没拿到数据”直接写成“无货”。页面是好看了,结果全是猜的。

所以代码里保留了四种状态:

状态含义
可取货官网明确返回可取货
暂无供应官网明确返回不可取货
未知没拿到可信库存字段
已过期曾经查到结果,但太久没有刷新

👽人话解释
“没查着”和“没有货”差得可远了。医院没拿到你的化验单,不能直接宣布你身体倍儿棒。

我让 Codex 把这条规矩写死:官网明确返回布尔值,才允许更新库存。字段缺失、接口报错、门店对不上,继续显示未知。

第一步算是摸清了字段,可新问题又来了:总不能为了监控 32 个配置,先往购物车塞 32 台手机吧?

🔍第二步:购物车不够用,继续找商品页接口

继续抓。

这次不看购物车,回到商品详情页,选择型号和门店,再打开“供货情况”。Network 里出现了另一个到店取货接口:

/shop/retail/pickup-message

请求里带一家门店和多个货号:

store=R471
parts.0=MJT74CH/A
parts.1=其他货号

store 是门店编号,parts.0parts.1 是商品货号。一个请求可以带多个货号,不需要先加购物车。

这下路走通了。

我让 Codex 整理商品目录,把机型、容量、颜色映射到真实货号,再做一个配置页面。选好门店和配置,程序自动拼出请求。

一开始我还想多选门店,青岛、济南一起盯。很快又把它砍了。

门店越多,单轮请求越多,触发限制的概率也越高。最后改成门店单选,型号、容量和颜色多选。同一门店的多个货号合成一次请求,够用,也省请求。

分析商品页到店取货接口响应

💥第三步:接口通了,HTTP 541 又来了

到这里,页面有了,商品也能查了。我自然想让结果再快一点。

60 秒太慢?那就 10 秒。

10 秒还不够快?保存配置以后立刻查。

很快,接口开始返回 HTTP 541,正文还是一张 Page Not Found 页面。

页面上又变成一排“未知”。

我先后让 Codex 检查请求头、接口参数、Cookie、无痕窗口,还讨论过换成 Python 自动化。折腾一圈,没有找到什么神奇开关。

后来把多轮日志放到一起看,规律出来了:限制窗口内,同一请求反复返回 541;等一段时间,它又会恢复 200。请求头换来换去,结果没变。

换 Python 也解决不了这个问题。请求频率和网络环境没变,外面套什么语言都一样。

最后采用的办法很朴素:少查,失败就等,别跟官网较劲。

最终策略是:

  1. 正常查询默认 120 秒一次。
  2. 一次请求合并当前门店的多个货号。
  3. 连续遇到 541 后进入冷却。
  4. 冷却时间按 5、10、20、30 分钟逐档增加。
  5. 冷却到点只发一次探测,成功再恢复正常轮询。
const COOLDOWN_STEPS = [300, 600, 1200, 1800];

程序还给每次请求加了 20 秒超时。官网一直不回,也不能让页面永远挂在那里。

👽人话解释
541 出现以后,继续猛点刷新就像电梯按钮没亮,拿手指一顿狂戳。电梯不会来得更快,按钮倒是快让你按秃了。

这套策略不能消灭 541,但能在撞上以后及时收手。库存仍然显示未知,不会被误报成无货。

风控问题稳住了,我以为终于能用了。结果点完“保存并监听”,页面半天没反应。

苹果库存接口返回 HTTP 541

🧩第四步:把查询放回日常 Chrome

单独在 Node.js 里请求,和日常打开苹果官网的 Chrome 不在同一个会话里。手动复制 Cookie 麻烦、容易过期,也不适合长期运行。

于是 Codex 给项目补了一个本机 Chrome 扩展,它只负责三件事:

  1. apple.com.cn 页面里获取官网正常产生的库存响应。
  2. 按看板保存的配置发起低频库存查询。
  3. 把结果传给 127.0.0.1 上的本机服务。

页面、扩展和官网的关系也很简单:

本机看板 → Chrome 扩展 → 苹果库存接口
    ↑                       ↓
    └──────── 库存结果 ────────┘

看板只监听 127.0.0.1,扩展权限也只给苹果官网和本机地址。真实 Cookie 不落进配置文件,更不会提交到仓库。

不过扩展接上以后,还有最后一个速度问题。

有一次追踪日志显示,Apple 接口只用了 586ms,整个流程却花了 18 秒。真正耗时的地方叫“等待扩展”,占了 17 秒多。

接口很快,结果为什么回来这么慢?

继续查,原因落在 Chrome 后台标签页。原来的扩展靠定时器读取新配置,标签页进了后台以后,定时器会被浏览器降频。

后来改成本机长轮询。保存配置时,服务端推送新的版本号,扩展收到以后马上查询;500ms 的页面检查只留作断线兜底。

为了不再靠感觉猜,Codex 还把一次查询拆成五段:保存请求、等待扩展、Apple 请求、解析传输、页面渲染与通知。以后慢在哪儿,看日志就知道。

🔔第五步:结果出来以后,别让我一直盯着

查询已经稳定,最后才轮到最开始的需求:有货叫我。

每次接口完成,看板都会更新对应配置。只有商品从“未知”或“暂无供应”变成“可取货”,程序才触发提醒。

提醒有两种:

  • 浏览器播放一声短提示音。
  • 桌面弹出通知,显示机型、容量、颜色和门店。

持续有货不会重复提醒。要不然两分钟叫一次,手机没买到,人先被逼疯了。

if (Notification.permission === 'granted') {
  new Notification(`${event.modelName} 可取货`, {
    body: `${event.capacity} · ${event.colorName} · Apple ${event.storeName}`
  });
}

库存看板显示商品可取货

🛠️第六步:把工具交付成能直接用的样子

到这里,最初那四条目标终于串起来了:

  • 选择地区、Apple Store、机型、容量和颜色。
  • 在一个请求里查询当前门店的多个货号。
  • 区分可取货、暂无供应、未知和已过期。
  • 遇到 541 自动退避,并显示下次探测时间。
  • 记录保存、等待扩展、官网请求、解析和渲染分别用了多久。
  • 到货时播放声音并发送桌面通知。
  • 在 Windows 上打包成单文件启动器。

项目代码已经放到 Gitee:

apple-store-inventory-monitor

目前有两种运行方式。

  • 想看代码、方便修改,用源码运行。
  • 只想打开就用,直接运行 Windows EXE 包。

两种方式都要安装一次 Chrome 扩展。扩展负责在日常 Chrome 的苹果官网环境里查询库存,本机看板负责配置、展示和提醒。

🧰方式一:源码运行

适合开发者,后面想改门店目录、页面样式或查询逻辑,都从这里开始。

第一步,准备环境。

电脑需要安装:

  • Node.js 22
  • Google Chrome
  • Git,可选;不想用 Git,直接下载仓库 ZIP 也行

把项目下载到本地:

注意分支:main

git clone https://gitee.com/javadog-net/apple-store-inventory-monitor.git
cd apple-store-inventory-monitor

第二步,安装依赖。

npm.cmd ci

第一次安装需要等一会儿。完成后可以先跑测试,确认当前环境没问题:

npm.cmd test

看到测试全部通过,再启动本机服务:

npm.cmd start

终端出现下面这个地址,说明服务已经起来了:

库存看板:http://127.0.0.1:4318

通过源码启动库存服务

第三步,安装 Chrome 扩展。

扩展只需要安装一次:

  1. Chrome 地址栏打开 chrome://extensions/
  2. 打开右上角“开发者模式”。
  3. 点击“加载已解压的扩展程序”。
  4. 选择项目里的 chrome-extension 文件夹。
  5. 扩展列表出现“Apple 库存本机桥接”,说明加载成功。

以后扩展代码更新了,就回到这个页面点一次“重新加载”,再刷新已经打开的 Apple 官网标签页。

打开 Chrome 扩展管理页

选择本地扩展文件夹

Apple 库存本机桥接扩展加载成功

第四步,打开看板和苹果官网。

浏览器打开两个页面:

http://127.0.0.1:4318/
https://www.apple.com.cn/iphone/

Apple 官网标签页不要关,它是扩展执行库存查询的地方。看板顶部显示“日常 Chrome 已连接”,说明本机服务和扩展已经接上。

库存看板显示日常 Chrome 已连接

第五步,保存监听条件。

在看板中依次选择地区、门店、型号、容量、颜色和查询间隔,点击“保存并监听”。第一次保存时,Chrome 会询问是否允许桌面通知,选择允许。

保存后会立即查询一次。运行记录里能看到门店、SKU、HTTP 状态和耗时;后续按设置的间隔自动检查。

要停止源码服务,回到 PowerShell 按 Ctrl+C。源码运行日志保存在:

.local\apple-api.log

📦方式二:Windows EXE 运行包

注意分支:feat/windows-single-file-launcher

Gitee 仓库源码分支

如果只是自己盯库存,不准备改代码,EXE 更省事。目标电脑不需要安装 Node.js。

Gitee 仓库 Windows 运行包

第一步,解压运行包。

运行包里至少保留下面两项:

Apple库存监控.exe
chrome-extension\

EXE 已经内嵌库存看板、商品目录和门店目录。chrome-extension 不能删,第一次使用还要从这个文件夹加载扩展。

第二步,加载 Chrome 扩展。

还是打开 chrome://extensions/,开启开发者模式,点击“加载已解压的扩展程序”,这次选择运行包里的 chrome-extension 文件夹。

如果之前通过源码方式加载过同一个扩展,可以继续使用,不用重复添加。

第三步,双击启动。

双击:

Apple库存监控.exe

Windows 库存监控 EXE 文件

启动器会自动完成三件事:

  1. 在本机启动 127.0.0.1:4318 库存服务。
  2. 用日常 Chrome 打开库存看板。
  3. 再打开 Apple 中国官网,供扩展查询库存。

当前 EXE 没有代码签名。Windows SmartScreen 可能提示“未知发布者”,确认文件来自自己的构建或可信发布地址后,再选择“更多信息 → 仍要运行”。

运行 EXE 自动打开库存看板和苹果官网

再次双击 EXE,不会再启动一个重复服务,只会打开已经运行的看板。

第四步,选择配置并开始监听。

操作和源码版完全一样:选地区、选一家门店,再选型号、容量和颜色,最后点击“保存并监听”。顶部显示 Chrome 已连接,运行记录出现 Apple 请求,才算真正开始工作。

保存门店和商品监听配置

关闭浏览器页面不会自动结束服务。停止 EXE 要在黑色控制台窗口按 Ctrl+C,或者直接关闭该控制台窗口。

EXE 运行日志保存在:

%LOCALAPPDATA%\Apple库存监控\apple-api.log

如果想自己从源码构建 EXE,需要 Node.js 22.20.0 或更高的 Node 22:

npm.cmd ci
npm.cmd run build:win

构建完成后,文件位于:

dist\Apple库存监控.exe

👽人话解释
源码版适合继续折腾,EXE 版适合直接开机干活。两边库存逻辑一样,区别只是启动方式。

项目测试覆盖了库存解析、单门店约束、541 冷却、配置推送、通知状态和页面交互。自动测试不会访问苹果官网,避免跑一次测试就给官网增加一轮请求。


源码

【公众号】JavaDog程序狗,回复【Apple库存监控】即可免费获得

公众号回复关键词获取运行包


评论