「这个价格是不是真的便宜」是购物中最容易判断错的一件事。平台展示的原价、折扣标签、限时倒计时,全部由卖家决定;而唯一客观的参照物是这件商品自己的历史价格。问题在于,历史价格你不记,平台也不会主动给你。
解决方案分三层,成本递增、可控性也递增。这篇把三层都说清,包括哪些工具是开源可自建的,哪些是闭源商业产品、需要把浏览数据交出去——这个区别比功能差异重要得多。
三层方案,先看怎么选
| 层 | 代表工具 | 覆盖范围 | 数据在哪 | 上手成本 |
|---|---|---|---|---|
| 浏览器插件 | Camelizer、Keepa、PriceLasso、Distill | 主流电商平台为主 | 多数在厂商服务器 | 装完即用 |
| 自托管自建 | changedetection.io、PriceBuddy | 任意网页 | 全在自己机器上 | 需要一台常开的机器 |
| 自己写脚本 | 三十行 Python | 任意网页 | 全在本地 | 需要改少量配置 |
选择逻辑很简单:只买主流平台的东西 → 插件;要盯冷门站点或者在意隐私 → 自建;有技术意愿、想要完全可控 → 脚本。
插件层:实测可用的一批
插件层是见效最快的,但这里必须把开源与闭源分开说。
CamelCamelCamel / Camelizer。免费且没有付费墙,历史数据保留时间最长,界面直接给曲线图。只支持 Amazon,价格提醒只能按金额设、不能按百分比,提醒渠道只有邮件。它还有个配套站点覆盖 Walmart 的历史价格。适合「偶尔想验证一下折扣真假」的人。
Keepa。Amazon 价格数据最细的一家,插件直接在商品页嵌入可交互图表,数据点密集。免费版就能用,完整功能需要订阅(约每月 19–29 美元档)。同样只支持 Amazon。如果你经常在 Amazon 买东西,它的免费部分已经够用。
PriceLasso。覆盖面比前两个广,支持 250 多个商店(Amazon、Walmart、eBay、Costco、Wayfair 等),带提醒和历史图表。适合不在 Amazon 下单为主的人。
Distill Web Monitor。思路完全不同:它不是「比价插件」,而是监控网页上指定元素的本地工具。你在页面上点选价格那个位置,它按你设的频率检查,变了就提醒。因为是在本地运行检查,所以不受平台白名单限制——任何网站都能盯。
HARPA AI。把「选元素监控」和 AI 结合起来,任意站点,本地处理,可以设价格下降、文本变化、补货等触发条件,检查间隔从十几秒到每月,也支持 webhook 转发。注意它是闭源商业产品,免费额度有限。
Honey。功能上有价格追踪和优惠码自动尝试,覆盖数千个站点。但它有过关于数据收集和联盟佣金行为的诉讼争议,浏览器扩展商店的政策也因它收紧过。要用之前建议先了解这段背景。
另外几个顺手可用的:Google 自带的购物价格追踪(在 Google 应用或 Chrome 里就能开启,也支持机票价格)、Capital One Shopping(覆盖十万家以上商店的比价)。这两个都是闭源服务。
关于国内平台要说清楚:上面这些插件价格历史基本只覆盖海外电商。国内平台没有公开的价格历史接口,想看历史价格只能自己盯——这正是 Distill 或自托管方案的价值所在。如果你在盯的是国内平台的商品页,直接跳到下面的第二层或第三层。
自托管层:两个值得装的开源项目
自托管的本质是:数据在你自己机器上,覆盖范围由你决定,没有平台白名单限制。代价是需要一台常开的设备(旧笔记本、树莓派、小主机都行),以及一次 Docker 部署。
changedetection.io(Apache-2.0,Python)是这个品类里最成熟的开源项目,GitHub 上 3 万多 star、两百多个版本迭代。它的定位是「网页变更监控」而不只是比价,所以能力比插件宽得多:
- 可视化选择器:点一下页面上要盯的元素,自动生成选择器,不用手写 CSS/XPath
- 过滤与触发规则:只提取价格数字做比较,忽略时间戳、广告位这些每次都变的噪声——这一步是所有监控工具能不能用下去的关键
- 价格与补货专用模式:能从商品页的元数据和结构化数据里提取价格,支持价格历史、阈值提醒、补货通知
- 浏览器步骤:检查前自动执行点击、填表、登录等动作,所以能监控需要交互或登录后才显示的价格
- 通知渠道极全:底层用 Apprise,支持邮箱、Telegram、Discord、ntfy、Gotify、Slack、webhook 等几十种
部署就是一行 Docker 命令,数据存在本地卷里,不需要额外数据库。官方也有托管版(每月 9 美元左右),但自建版是完整功能。
PriceBuddy(jez500/pricebuddy)是另一条路线,专注做「比价」这件事本身:把同一件商品在多个商店的链接都加进去,然后比较当前最优选项。几个别的工具没有的能力:
- 单位价格比较:10 包装和 3 包装能算出每单位多少钱,避免被包装规格迷惑
- 库存状态跟踪:区分现货、预售、缺货、停售——便宜但永远没货的链接没有意义
- 可选 AI 辅助:页面结构怪异导致抓不到数据时,可以接 OpenAI、Anthropic、Gemini 或者本地 Ollama 来修复抓取规则。默认关闭,只有需要时才开
- 自带浏览器扩展:PriceBuddy Companion(Chrome/Edge),在商品页上直接开始追踪、对比你已追踪的其他商店价格
它也是 Docker 部署,自带定时任务,不需要单独配 cron。有一点需要知道:默认会给少数商店加联盟参数,可以在配置里关掉(设 AFFILIATE_ENABLED=false)。
脚本层:三十行,零依赖
如果不想要一台常开的机器,也不想装 Docker,可以退回到最原始的方式:一个 Python 脚本,跑一次检查一遍,有降价就提醒。只用标准库,不需要 pip install 任何东西。
import json
import os
import re
import sqlite3
import urllib.request
from datetime import datetime
DB = os.path.join(os.path.dirname(os.path.abspath(__file__)), "prices.db")
UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/126 Safari/537.36"
def init():
con = sqlite3.connect(DB)
con.execute("""CREATE TABLE IF NOT EXISTS history (
url TEXT, price REAL, ts TEXT)""")
con.execute("""CREATE TABLE IF NOT EXISTS target (
url TEXT PRIMARY KEY, target REAL)""")
return con
def fetch(url):
req = urllib.request.Request(url, headers={"User-Agent": UA})
with urllib.request.urlopen(req, timeout=20) as r:
return r.read().decode("utf-8", "ignore")
def extract(html, rule):
kind = rule.get("type", "regex")
if kind == "regex":
m = re.search(rule["pattern"], html)
if not m:
return None
raw = m.group(1) if m.groups() else m.group(0)
return float(re.sub(r"[^d.]", "", raw))
if kind == "json":
data = json.loads(html)
for key in rule["path"].split("."):
data = data[key]
return float(re.sub(r"[^d.]", "", str(data)))
return None
def notify(url, old, new, hook):
msg = "降价 %s %.2f -> %.2f" % (url, old, new)
print("ALERT " + msg)
if not hook:
return
body = json.dumps({"topic": "price", "title": "降价提醒", "message": msg}).encode()
req = urllib.request.Request(
hook, data=body, headers={"Content-Type": "application/json"})
try:
urllib.request.urlopen(req, timeout=10).read()
except Exception as e:
print("notify failed: %s" % e)
def run(config, hook=None):
con = init()
for item in config["watch"]:
url = item["url"]
try:
html = fetch(url)
price = extract(html, item)
except Exception as e:
print("SKIP %s (%s)" % (url, e))
continue
if price is None:
print("NOPRICE %s" % url)
continue
row = con.execute(
"SELECT MIN(price) FROM history WHERE url=?", (url,)).fetchone()
lowest = row[0] if row and row[0] is not None else price
con.execute("INSERT INTO history VALUES (?,?,?)",
(url, price, datetime.now().isoformat(timespec="seconds")))
con.commit()
changed = "" if price >= lowest else " (新低)"
print("%.2f %s%s" % (price, url, changed))
if price < lowest:
notify(url, lowest, price, hook)
if item.get("target") and price <= item["target"]:
notify(url, item["target"], price, hook)
con.close()
if __name__ == "__main__":
cfg_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "watch.json")
with open(cfg_path, encoding="utf-8") as f:
cfg = json.load(f)
run(cfg, cfg.get("notify"))
配套的配置文件 watch.json,用正则从页面里取价格:
{
"notify": "https://ntfy.sh/你的私有主题",
"watch": [
{
"url": "https://example.com/product/123",
"type": "regex",
"pattern": "price-now[^0-9]{0,20}([0-9][0-9,]*\.[0-9]{2})",
"target": 299
},
{
"url": "https://example.com/api/item/456",
"type": "json",
"path": "data.price.current",
"target": 99
}
]
}
三个设计要点,都是踩过坑才明白的:
- 只在「创新低」时提醒,不是每次变化都提醒。前者一年响几次,后者一天响几次,后者你三天就会关掉通知
- 把历史存进 SQLite,这样「当前价是不是历史最低」才有判断依据,顺便攒出自己的一份价格曲线
- 正则要锚定到价格附近的特征串(比如
price-now这样的类名),而不是只匹配数字。只匹配数字会把页面里所有数字都抓进来
定时运行:Linux/macOS 用 crontab,Windows 用任务计划程序,一天跑两三次就够。频率不要设太高——既会给对方服务器造成压力,也容易触发反爬。
这些坑要提前知道
抓取频率要克制。对第三方站点高频请求在技术上是压力、在观感上接近滥用。商品价格一天变几次?两次检查足够了。
选择器会失效。平台改版后元素位置变了,监控就会抓到空值或者错误内容。所有这类工具都需要偶尔回头看一次是否还正常。判断方法很直接:如果一条监控连续很久没有任何变化,先怀疑它坏了,而不是价格真的半年没动。
比较价格要统一口径。含税不含税、含运费不含运费、会员价还是普通价、优惠券是否叠加——不统一口径的比价等于没比。
别只看单价。价格下降 15% 但规格从 12 片变成 9 片,实际是涨价。这就是单位价格比较的价值所在。
插件权限要看一眼。装一个「读取和更改你在所有网站上的数据」的扩展,等于把全部浏览行为交给它。开源可自建的工具在这件事上有天然优势,因为你可以查证它到底做了什么。
放到国内电商场景,做法要改一改
本文的插件和自托管方案以海外电商为默认场景,直接搬到国内会遇到两个问题:一是国内电商平台的反爬机制严格,写脚本抓取通常违反平台服务条款;二是国内有自己的「价保」机制,很多时候不需要自己去抓价,直接申请退差价就行。
更适合国内的做法是三步:先确认这个类目支不支持价保、窗口多长;下单后用低频记录的方式盯住价格(一天一到两次,人工打开页面,不并发、不绕验证码);一旦降价,把提醒推到微信,落地到「申请价保」这个动作上。国内电商比价与价保:差价其实是可以要回来的里给了完整的规则说明、推送通道对照表和一个纯标准库的监控脚本。
常见问题
不用 Docker、不写脚本,有没有更省事的办法?
有。先用 Google 自带的购物价格追踪(在 Chrome 或 Google 应用里就能开),对主流商品已经够用。再补一个历史价格插件用于验证折扣真假。这套组合不用花一分钱,也不用部署任何东西——等你发现经常要盯非主流站点时,再考虑自托管的方案。
自托管方案需要什么样的硬件?
要求很低。这类工具本身很轻,一台能常开的旧笔记本、树莓派或者一两百块的小主机都够。真正需要注意的是三点:能长期开机、网络稳定、不要把服务直接暴露到公网而不加认证——如果你要在外面访问,至少加一层反向代理和密码。
这些工具能保证买到最低价吗?
不能,也不需要。它们的实际作用是让你在「限时折扣」面前不再凭感觉判断。知道某个价格在历史区间的什么位置,就已经解决了大部分决策问题。剩下的部分——你是真需要,还是只是想买——工具帮不了。




评论 (0)