闲鱼捡漏怎么做到秒级响应?用 AI 编程搭一套自动监控提醒系统

手动刷闲鱼抢不到漏,因为你在跟脚本抢。这篇讲怎么用 AI 编程搭一套自动监控:拦截接口拿结构化数据、按价格分位算评分、过滤维修机和危险词、企业微信秒级推送、计划任务常驻部署,附实测数据与翻车点。
闲鱼捡漏自动监控系统搭建教程
闲鱼捡漏自动监控系统搭建

先说结论:手动刷闲鱼抢不到漏,不是你手慢,是你在跟一堆脚本抢。真正的好货上架后,留给你的人工反应窗口通常只有几十秒到两三分钟,而这段时间里至少有几十个监控程序已经收到推送了。

这篇文章讲的是怎么用 AI 编程(也就是最近很火的 vibecoding)把一套闲鱼捡漏监控系统搭起来:它自动盯关键词、按发布时间排序、算出这个价格是否真的偏低、然后第一时间推到你手机上。代码是能跑的,不是伪代码。

一、先看清战场:你手刷闲鱼到底输在哪

很多人以为捡漏靠的是”多刷”。刷了几周发现,好东西永远在点进去的那一秒被人拍下。这里面有三层原因,逐层拆开看。

1.1 信息到达速度差了一个数量级

闲鱼商品的曝光是按排序算法分发的。默认排序是”综合”,掺了推荐权重;而捡漏必须看按发布时间倒序——因为真正的低价货往往上架几分钟内就被拿走,只有在”最新”这个维度里才排得靠前。

人工刷的节奏大概是每几分钟一次,还得切页面、翻列表、看详情。脚本的节奏是每 30 秒一轮,一轮拉 30~50 条结构化数据,纯数字比对。这个差距不是勤奋能弥补的。

1.2 你看到的是标题,脚本看到的是字段

人在列表页能读到的信息量其实很少:一张图、一行标题、一个价格。而接口返回的 JSON 里还有:发布时间戳、卖家 ID、卖家信用、历史在售数量、商品描述全文、是否支持验货、浏览量、想要人数。

把这些字段串起来判断,能过滤掉 90% 的假漏:比如”全新未拆封”却是个人卖家、价格低到离谱但描述里写着”仅展示”、同一个卖家每天上架十个同款——这些人在列表页根本看不出来。

1.3 捡漏的本质是价格异常检测

换个说法你可能更清楚:捡漏不是”找便宜的东西”,是找出明显偏离市场价的报价。这就要求你手里有一份”这个型号正常卖多少钱”的基准线,然后对新上架的商品做偏离度计算。

手动做这件事是不可能的——你不可能记住三十个型号的价格分布。而这件事恰好是程序最擅长的。

维度 人工刷 脚本监控
扫描间隔几分钟,且不连续30 秒,7×24 小时
单轮覆盖10~20 条30~50 条结构化字段
判断依据价格 + 眼缘价格分位 + 卖家信用 + 描述关键词
响应延迟看心情,深夜基本失效上架后 30 秒内推送

二、什么才算”漏”:把标准量化下来

不定义标准就写不出判断逻辑。我给三个可量化的指标,你可以照着调。

2.1 价格分位,不是价格绝对值

不要用”低于 3000 元就提醒”这种绝对阈值——同一个关键词下可能同时存在 800 元的配件和 8000 元的整机。正确做法是动态基准:

  • 每轮抓到的同关键词商品,取价格的 25 分位数当作该品类的”低位线”;
  • 新上架商品价格低于该分位线的 70%,标记为”疑似漏”;
  • 低于 50%,标记为”高危漏”,优先推送并加粗。

为什么用分位数而不是均价?因为均价会被顶配机型拉高,中位数附近才是真实的成交密集区,分位数对异常值更不敏感。

2.2 卖家质量分

同样低价,个人卖家和批量商家完全是两回事。我按四个信号打分:

信号 加分 减分
卖家信用等级极好 / 优秀 +30中等及以下 −20
在售商品数量1~3 件 +20(个人闲置)≥20 件 −30(职业卖家)
描述完整度有实拍图 + 序列号 +100 字以上 +15描述空 / 只有表情 −15
危险词—见下方清单 −40

危险词清单(命中直接降权,不推送):仅展示、拍前联系、加微信、定金、代拍、无图勿拍、展示机、不支持验货。这几个词是二手交易的经典话术,出现任意一个,价格再低也不值得抢先。

2.3 时间窗口

只推 24 小时内新上架的。超过一天还挂着的东西,要么是价格压根不低,要么是货有问题——真正的好货不会停留那么久。这条规则能砍掉绝大部分噪音。

2.4 一个真实例子:2800 的 M2 Air 为什么不能要

说个具体场景,你就能明白为什么必须把判断逻辑写细。

搜”MacBook Air M2″,当轮抓到 40 条,价格 25 分位是 4600。这时出现一条 2800 的,成色写”9 成新”,卖家信用”优秀”,在售商品只有 2 件——按前面三条规则算下来,评分直接冲到 90 分以上,属于必须立刻推的类型。

但你点进去会发现描述里有一句”主板修过,功能正常”。这句话让整件事的性质变了:修过主板的机器,二手残值要打对折,2800 其实是正常价甚至偏高。而在列表页,你根本看不到这句话。

所以要加第四条规则:维修类关键词单独处理。维修、换过、拆机、进水、主板、屏幕换、电池换、非原装、无保修 这些词出现,不是简单地减分,而是直接把价格基准乘以 0.6 再比——因为这类机器的合理价本来就低一大截。

这一条是我跑了半个月才补上的。最开始那几天推了七八台”超值”机器,全是修过的。所以别指望一次把规则写全,先跑起来,每误报一次就加一条,两周之后就稳定了。

2.5 监控几个关键词才合适

新手常犯的错是一次挂二十个关键词,结果一小时请求量爆掉,账号先被限流。

按前面说的频率上限(每小时 120 次)算,30 秒一轮的情况下,同时监控 3 个关键词就是合理上限。每多一个词,单轮的耗时就多 2~3 秒,轮询间隔就得拉长,响应速度反而下降。

如果你确实想看更多型号,正确的做法是分层:

  • 核心词(1~2 个):你真正想买的那一两个型号,高频盯,30 秒一轮;
  • 外围词(3~5 个):相邻型号或替代品,低频扫,10 分钟一轮就够;
  • 机会词(不限):不定时手动搜,看到价格明显偏离再临时加进监控。

关键词本身也有讲究。别用太宽的词——”显卡”这个词一天几千条新上架,你的脚本会被淹没;也别用太窄的词——”RTX 4070 Ti SUPER 白魔龙”可能一周都没一条。合适的粒度是「型号 + 一个必要限定」,比如”RTX 4070 Ti 自用”、”MacBook Air M2 16G”,既过滤掉商家批量上架,又保留足够的商品量。

还有个技巧:把关键词拆成两轮跑。第一轮搜精确词拿高质量结果,第二轮搜泛词但只保留标题匹配型号的——这样覆盖面和精度都能兼顾,代价是耗时翻倍。

三、三条技术路线,只有一条能长期跑

能拿到闲鱼数据的方式有三种,我全试过,直接给结论。

3.1 官方开放平台

阿里的开放平台有闲鱼相关接口,但需要企业资质、应用审核、还要签协议,个人拿不到。而且商品搜索这类接口通常不对外开放——这属于平台核心数据,不会给第三方随便调。这条路对个人直接排除。

3.2 直接逆向 App 接口

抓包能看到 mtop.taobao.idlemtopsearch.pc.search 这类接口,返回的就是干净 JSON。但每次请求都要带 sign 参数,算法是 md5(token + "&" + t + "&" + appKey + "&" + data),其中 token 来自 cookie 里的 _m_h5_tk,且每 24 小时失效要重新取。

能跑,但维护成本高:接口版本一变、风控策略一紧,就得重新调。如果你只是想自己用,不值得投入这个精力。

3.3 浏览器自动化,拦接口响应(推荐)

用 Playwright 打开真实的搜索页,让浏览器自己去完成登录态、签名、风控挑战,我们只在网络层把 JSON 响应截下来。这是成本最低、最不怕改版的做法:只要网页还能用,脚本就能跑。

代价是慢——每次要起浏览器、等页面加载,一轮大概 3~8 秒。但捡漏这件事,30 秒一轮和 3 秒一轮对结果没有本质差别,因为你比的是「别人多久推送到」,不是「CPU 有多快」。

3.4 为什么不用 Selenium

有人会问,既然都是浏览器自动化,Selenium 不行吗?行,但要多写不少东西。

Playwright 原生支持 page.on("response") 拦截网络响应,拿到结构化 JSON 是一行代码的事;Selenium 要拦住响应,得额外挂一个 browsermob-proxy 之类的代理进程,配置链路长一倍,出问题排查起来也麻烦。

另外两点:Playwright 的自动等待做得更彻底(元素出现前点了会自己等,Selenium 要手写 WebDriverWait);它的 launch_persistent_context 直接支持状态持久化,Selenium 得自己管 user-data-dir 参数。这两条省下来的调试时间,比学习成本高得多。

当然如果你手上已经有成熟的 Selenium 代码,也没必要重写——逻辑是通的,只是拦截响应那部分要多费点劲。

🔧 我整理的软件库

这些年折腾服务器、虚拟化和开发环境,装过的系统镜像、运维工具、开发套件、数据库与中间件,我都归档在自建的文件库里,持续补充新版本。没有弹窗广告,不强制注册,需要什么直接取。

进入软件库 →

常用工具随手可取 · 不定期补档

四、动手之前必须先解决的三件事

很多人卡在这一步就放弃了,其实都是同一个原因:没想清楚数据从哪来、身份怎么维持、频率怎么控。

4.1 登录态怎么保

闲鱼的搜索接口未登录也能访问一部分,但返回的数据会缺字段,而且很快就触发验证。正确做法是第一次手动登录,然后把浏览器状态持久化下来,后续每轮复用同一份 User Data 目录,不要每次新开干净会话。

context = await pw.chromium.launch_persistent_context(
    user_data_dir="./profile",          # 登录态存在这里,只登录一次
    headless=False,                     # 首次建议有头,方便过验证
    args=["--disable-blink-features=AutomationControlled"],
)

首次运行会弹出浏览器,你手动扫码登录一次,之后关掉、改成 headless=True 就能无人值守。cookie 一般能撑几天到两周,失效了脚本会检测到并提醒你重新登录。

4.2 频率怎么控

这是最容易翻车的地方。我的经验值:单账号每小时不超过 120 次搜索请求,也就是平均 30 秒一次,且每轮之间加 5~15 秒随机抖动。不要图快用 1 秒一轮——那不是捡漏,那是给风控系统送样本。

另外几个降低风险的细节:

  • 同一轮里串行搜索多个关键词,不要并发;
  • 不要每次都从第一页开始,轮换 page=1/2/3;
  • 夜间(0:00~7:00)频率降到每小时 40 次;
  • 遇到验证码立刻停 30 分钟,不要硬刚。

4.3 数据存哪

需要一个地方存”已经推送过的商品 ID”,避免重复提醒。SQLite 足够,一张表就行:

CREATE TABLE IF NOT EXISTS seen (
    item_id   TEXT PRIMARY KEY,
    title     TEXT,
    price     REAL,
    seller    TEXT,
    ts        INTEGER,
    pushed    INTEGER DEFAULT 0
);

加上这张表之后,脚本重启也不会重复推同一件商品,这是让它能长期安静跑下去的关键。

五、让 AI 把代码写出来:vibecoding 的实际用法

这套东西我自己写大概要一天,用 AI 辅助是两三个小时。但前提是你得会提需求。很多人抱怨”AI 写的代码跑不起来”,问题通常不在模型,在提示词。

5.1 分步要,不要一次要全套

错误示范:”帮我写一个闲鱼捡漏监控程序,要能自动搜索、判断价格、推送消息、存数据库。”——这种需求给出来,AI 只能给你一个能编译但跑不通的骨架。

正确做法是拆成四步,每步单独验证:

步骤 要 AI 做什么 验收标准
① 探针只做一件事:打开搜索页并把商品 JSON 打印出来能打印出 10 条以上带价格的记录
② 解析把 JSON 映射成商品对象,落 SQLite数据库里有数据、字段完整
③ 判断加分位计算和危险词过滤喂历史数据,能准确挑出你认可的那几条
④ 推送接 webhook 发消息手机上真的收到一条

关键是每一步都要跑通再往下。第①步跑不通,后面全是白写。而第①步恰恰是最容易出问题的(选择器变了、接口名变了),所以先攻它。

5.2 把报错原样贴回去

不要自己总结”好像报了个错”。完整复制报错栈,包括文件路径和行号。AI 看到 TimeoutError: locator.click: Timeout 30000ms exceeded 和看到”点击失败”能给出的方案完全不同。

5.3 让 AI 先写判断逻辑,你只调参数

评分那部分别让 AI 拍脑袋定权重。告诉它你的规则,让它只负责实现:

按以下规则给商品打分,输出 0-100 的整数和命中原因列表:
1. 价格低于本轮同关键词 25 分位数的 70%:+40 分
2. 价格低于 50%:额外 +25 分
3. 卖家信用为"极好"或"优秀":+30 分
4. 卖家在售商品 1-3 件:+20 分
5. 描述含"仅展示/拍前联系/加微信/定金/代拍/不支持验货"任一:−40 分
6. 上架时间超过 24 小时:直接返回 0
给出 JSON:{"score": int, "reasons": [...]}

这样出来的代码你能看懂、能改。比让 AI 自己想一套评分模型靠谱得多。

六、完整实现:核心代码走一遍

下面是能跑的主体部分。用 Playwright 的异步接口,Python 3.11+。

6.1 拦截搜索结果

import asyncio, json, re
from playwright.async_api import async_playwright

SEARCH_API = "idlemtopsearch"

async def fetch_page(ctx, keyword, page=1):
    """打开搜索页,拦截 JSON 响应,返回商品列表"""
    url = (f"https://www.goofish.com/search?q={keyword}"
           f"&sortField=create&sortValue=desc&page={page}")
    got = {}

    async def on_response(resp):
        if SEARCH_API in resp.url and resp.status == 200:
            try:
                got["json"] = await resp.json()
            except Exception:
                pass

    p = await ctx.new_page()
    p.on("response", on_response)
    try:
        await p.goto(url, wait_until="domcontentloaded", timeout=30000)
        # 等接口回来,最多 12 秒
        for _ in range(120):
            if "json" in got:
                break
            await asyncio.sleep(0.1)
    finally:
        await p.close()
    return got.get("json")

这里有个细节:wait_until="domcontentloaded" 而不是 networkidle。闲鱼页面有长连接和轮询,用 networkidle 会一直等不到,直接超时。

6.2 从 JSON 里挖商品

返回结构层级比较深,商品列表通常在 data.resultList 里,每条记录的关键字段藏在 data.item.main.exContent 中,而它是一个JSON 字符串,需要二次解析:

def parse_items(raw):
    out = []
    if not raw:
        return out
    data = (raw.get("data") or {})
    for entry in (data.get("resultList") or []):
        item = ((entry.get("data") or {}).get("item") or {})
        main = item.get("main") or {}
        ex = main.get("exContent") or {}
        if isinstance(ex, str):
            try:
                ex = json.loads(ex)
            except Exception:
                ex = {}
        price = ex.get("price") or []
        if isinstance(price, list):
            price = price[0] if price else {}
        out.append({
            "item_id": str(main.get("itemId") or ex.get("itemId") or ""),
            "title":   main.get("title") or ex.get("title") or "",
            "price":   float((price or {}).get("price") or 0),
            "seller":  (ex.get("userNickName") or ""),
            "area":    (ex.get("area") or ""),
            "desc":    (ex.get("detailParams") or {}).get("detail", ""),
        })
    return [x for x in out if x["item_id"] and x["price"] > 0]

字段名在不同版本里会变。所以第一次跑一定要把原始 JSON 存一份下来,对着结构改映射——这也是为什么第①步的探针必须先跑通。

6.3 评分与去重

import sqlite3, statistics

BAD_WORDS = ["仅展示", "拍前联系", "加微信", "定金", "代拍", "不支持验货", "无图勿拍"]

def score_item(it, p25):
    reasons, score = [], 0
    price = it["price"]
    if p25 > 0:
        if price <= p25 * 0.5:
            score += 65; reasons.append(f"低于25分位一半({price:.0f}/{p25:.0f})")
        elif price = 40:
        score += 10; reasons.append("描述无危险词")
    return max(0, score), reasons

分位数用当轮抓到的所有价格算:

prices = [x["price"] for x in items]
p25 = statistics.quantiles(prices, n=4)[0] if len(prices) >= 8 else 0

样本少于 8 条时不算分位数——样本太少,这个基准没有意义,宁可不推。

6.4 主循环串起来

把上面几块拼成一个能连跑的主循环。要注意的是异常不能让它退出——网络抖动、页面改版、单条数据解析失败,都只能记日志继续,不能让整个进程死掉。

async def main_loop(keywords, webhook, interval=30):
    conn = sqlite3.connect("data.db")
    conn.execute(SCHEMA)
    async with async_playwright() as pw:
        ctx = await pw.chromium.launch_persistent_context("./profile", headless=True)
        while True:
            for kw in keywords:
                try:
                    raw = await fetch_page(ctx, kw)
                    items = parse_items(raw)
                    prices = [x["price"] for x in items]
                    p25 = statistics.quantiles(prices, n=4)[0] if len(prices) >= 8 else 0
                    for it in items:
                        if conn.execute("SELECT 1 FROM seen WHERE item_id=?",
                                        (it["item_id"],)).fetchone():
                            continue
                        score, reasons = score_item(it, p25)
                        if score >= 60:
                            await push(webhook, it, score, reasons)
                        conn.execute("INSERT INTO seen VALUES (?,?,?,?,?,1)",
                                     (it["item_id"], it["title"], it["price"],
                                      it["seller"], int(time.time())))
                    conn.commit()
                except Exception as e:
                    log.error("关键词 %s 本轮失败: %r", kw, e)
                    continue
                await asyncio.sleep(random.uniform(5, 15))
            await asyncio.sleep(interval)

这段代码有四个地方值得留意:seen 表在推送前查重(不是推送后写),避免重复推;每个关键词单独 try,一个挂了不影响其他;commit 放在关键词循环里而不是最外层,防止长时间不开事务;轮间 sleep 加随机抖动,别让它看起来像机器。

七、推送:让消息真的到达你手上

推送渠道选哪个都行,我常用企业微信群机器人,因为免费、不限量、手机上通知及时。

7.1 企业微信 webhook

import aiohttp

async def push(webhook, item, score, reasons):
    text = (f"🎯 疑似漏 · {score}分n"
            f"{item['title']}n"
            f"价格:¥{item['price']:.0f}  {item['area']}n"
            f"卖家:{item['seller']}n"
            f"https://www.goofish.com/item?id={item['item_id']}n"
            f"理由:{';'.join(reasons)}")
    async with aiohttp.ClientSession() as s:
        await s.post(webhook, json={"msgtype": "text",
                                    "text": {"content": text}})

群机器人的 key 在群设置 → 群机器人 → 添加 → 复制 Webhook 地址。注意别把 key 提交到公开仓库。

7.2 控制推送数量

这是体验的关键:宁可漏推,不要滥推。一个晚上弹二十条的监控,第三天你就会关掉它。我的做法是设三道闸:

  • 单条评分 ≥60 才推;
  • 每小时最多推 5 条,超出的写进数据库不推送;
  • 同一卖家 24 小时内最多推 2 条(防商家刷屏)。

八、让它常驻:两个平台的开机自启

脚本写好之后不能靠手动运行。两个平台各给一套。

8.1 Windows:计划任务

schtasks /create /tn "XianyuMonitor" /tr "C:Python313python.exe D:scriptsxianyu.py" ^
  /sc onstart /ru SYSTEM /rl HIGHEST /f

用 onstart + SYSTEM 账户的好处是不用登录也能跑,也不弹黑窗。想让它延迟启动(避免开机时抢资源)加 /delay 0002:00。

8.2 Linux:systemd

[Unit]
Description=Xianyu Leak Monitor
After=network-online.target

[Service]
Type=simple
WorkingDirectory=/opt/xianyu
ExecStart=/opt/xianyu/venv/bin/python monitor.py
Restart=always
RestartSec=30
User=xianyu

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now xianyu
journalctl -u xianyu -f     # 看日志

Restart=always 这句很重要:浏览器会偶发崩溃,或者遇到验证码后进程卡死。有它兜底,基本不用管。

九、实测数据:这套东西到底有多快

我用自己的关键词跑了三天,记录了一些数据,供你判断值不值得投入。

指标 实测值 说明
单轮耗时4.2~7.8 秒3 个关键词串行
上架→推送延迟中位 38 秒取决于轮询间隔
日请求量约 8600 次3 词 × 30 秒轮询
验证码触发3 天 1 次降频后明显减少
有效推送平均每天 4~9 条评分≥60 的
真实可捡约 1/5剩下的要么手慢要么货有问题

换个角度看这组数据:一天推 4~9 条,其中五分之一是真的可以下手——也就是说,每天有 1~2 个真正值得看的机会。这个密度比手动刷高得多,但也不是”躺着赚钱”。捡漏依然是概率游戏,脚本只是把概率从千分之一提到几十分之一。

十、六个容易翻车的地方

10.1 选择器写死

别依赖 CSS class 名(那些是打包生成的哈希,一周就变)。能用接口响应就别用 DOM 解析,接口字段名虽然也会变,但变更频率低得多。

10.2 把配件当成整机

搜”iPhone 15″,你会抓到大量手机壳、数据线、屏幕总成。价格分布被这些低价的干扰得完全失真。解决方式是标题白名单/黑名单:标题必须含机型关键词,且不含 壳、膜、线、支架、配件、维修。

10.3 忘记处理时区

接口返回的时间戳有的是秒,有的是毫秒。判断”24 小时内”的时候如果搞错一位,整批数据都会被判成超时,然后你一条推送都收不到,还以为是脚本挂了。

10.4 无头模式下拿不到数据

部分反爬会检测 navigator.webdriver。Playwright 起浏览器时加 --disable-blink-features=AutomationControlled,必要时再用 add_init_script 覆盖几个特征。如果还是拿不到,先用有头模式跑一次,确认是环境问题还是逻辑问题。

10.5 内存泄漏

每轮 new_page() 却忘记 close(),跑一天能吃掉几个 G。所有页面操作都套 try/finally,这是硬性要求。长期跑还要定期重启浏览器上下文。

10.6 把它当成”必然成功”

这套系统做的是信息前置——让你比别人早几十秒知道。但从知道到成交,中间还有沟通、议价、验货、付款一堆环节,每一步都可能被别人截胡。它的真实价值是:把”根本不知道有这回事”变成”知道了但没抢到”,这一步已经筛掉了 99% 的竞争者。

10.7 cookie 失效没有任何提示

最隐蔽的一个坑:登录态过期后,接口仍然返回 200,但 resultList 是空的。

如果你没做判断,脚本会安静地跑上一整天,一条数据都抓不到,而你还在等推送。修法是加一个健康检查:连续 5 轮抓到的商品数都是 0,就当作登录失效处理——推一条”需要重新登录”的提醒,然后暂停。这个判断比解析返回码更可靠,因为返回码在过期时通常还是 0(成功)。

如果你跑起来之后遇到具体问题——比如拿不到 JSON、验证码过不去、评分总是误报——可以直接找我:微信/手机 17712677007,说清楚现象和报错,我看看卡在哪一步。这类问题通常一两句话就能定位。

十一、边界:哪些事不要做

最后说清楚红线,免得跑偏。

  • 不要自动化下单和付款。自动抢拍涉及交易环节,风险极高,也容易触发平台规则。监控归监控,付款必须人来点。
  • 不要高频请求。前面说的 30 秒一轮、每小时 120 次是经验上限,别为了抢速度加倍——账号被封就全完了。
  • 不要倒卖账号和 cookie。这不是技术问题。
  • 不要拿它做批量采集建库。自己盯着几个型号用,和抓全站数据是两回事,后者是平台明确禁止的。

技术本身是中性的。同一套代码,用来给自己找一台便宜显卡是效率工具,用来批量抓数据卖钱就是另一回事了。这条线在哪,用的人自己清楚。

十二、写在最后

这套东西真正的门槛不是代码——现在有 AI 辅助,代码部分两三个小时就能出来。门槛在想清楚要监控什么、什么样的价格才算漏、哪些信号说明卖家不靠谱。这些判断做不出来,脚本再快也只是在给你推垃圾信息。

我的建议是先别急着写代码。花两天时间手动刷,把你看得上的每一条都记下来:价格、卖家、描述、你判断它值得的理由。攒够二十条,再回头看这些记录,标准自然就出来了。那时候写代码是水到渠成的事。

另外提醒一句:捡漏这件事有很强的时效性,同一套参数用三个月就会失效(市场价变了、竞争者变多了)。所以别把参数写死在代码里,放到配置文件,隔一段时间重新校准一次。

评论区可以说说你打算盯什么型号,或者已经在跑的过程中遇到了什么问题。

✍️ 关于作者

IT 峰哥,互联网技术从业者。日常折腾服务器、虚拟化、数据库与企业级应用,关注开源系统的二次开发与基础设施落地。这里记录的是踩过的坑和验证过跑得通的方案,不是转述文档。

交流:微信 / 手机 17712677007(注明来意,看到会回)

文中方案如有疏漏,欢迎在评论区指正 · 技术问题欢迎交流

给TA打赏
共{{data.count}}人
人已打赏
默认

Immich 自建相册怎么部署?手机照片自动备份到私有云,告别网盘年费

2026-11-7 22:35:22

默认

Mac 免费软件还能这么玩?晾衣绳截图、系统数据清理、状态栏三合一

2026-10-31 21:09:51

❯
购物车
优惠劵
搜索