你是不是也这样蹲过降价
双十一、618、品牌日,心里那个想买的东西价格忽上忽下。你是不是也干过这种事:把商品页加进收藏,每天点开七八回,就为了看它降没降。盯着屏幕眼睛酸,还经常错过最低点——等你刷到的时候,券已经抢光了。其实这种"反复刷新、人工比对"的活儿,最该交给电脑。今天我们就用 Python 写一个"价格哨兵":你只管把商品链接丢给它,一旦降价,它第一时间通知你。
这事儿,本质上就是 RPA 加上监控
说直白点,我们要干的活分三步:打开网页、读价格、比一比。第一步"打开网页读内容",正是 RPA(机器人流程自动化)最拿手的浏览器自动化;后面"定时检查 + 降价就报警",又是自动化运维里监控告警的思路。两个方向一结合,你就拥有了一个 24 小时不睡觉的盯价小助手。它不抢券、不下单,只负责"盯"和"喊你",安全又省心。
先准备两件小工具
只要装好一个库就能跑,不用会前端。第一件是 Playwright,专门用来让 Python 控制真实浏览器:
pip install playwright
playwright install chromium
第二件,是找到商品页"价格"长在哪。在浏览器里打开商品页,把鼠标移到价格数字上,右键选"检查",你会看到类似 <span class="price">¥219.00</span> 这样的代码。记下那个 class 名(这里是 price),待会告诉程序去哪抓数字就行。
核心代码:先盯一个商品
下面这段就是哨兵的"眼睛"。它打开网页,等价格出现,把文字读出来,再用正则抠出数字。
import json, re, os
from playwright.sync_api import sync_playwright
def extract_price(text):
# 从 "¥219.00" 这类文字里抠出数字
m = re.search(r"(\d+\.?\d*)", text)
return float(m.group(1)) if m else None
def check_price(url, selector):
with sync_playwright() as pw:
browser = pw.chromium.launch(headless=True)
page = browser.new_page()
page.goto(url, timeout=30000)
page.wait_for_selector(selector, timeout=10000)
text = page.locator(selector).inner_text()
browser.close()
return extract_price(text)
price = check_price(
"https://example.com/product/123",
".price",
)
print("当前价格:", price)
headless=True 表示浏览器在后台偷偷跑,不弹窗;wait_for_selector 会等价格元素加载好再读,避免抢到空值。第一次跑如果报缺浏览器,回头确认 playwright install chromium 执行过了。
一次盯一堆,还能记住上次的价
一个商品不过瘾?把要盯的都写进一个列表,循环检查,再用一个 JSON 文件记住"上次价格",这样才知道到底是涨是跌。
import json, os
WATCH_FILE = "prices.json"
PRODUCTS = [
{"name": "无线耳机", "url": "https://example.com/p/1", "selector": ".price", "target": 199.0},
{"name": "机械键盘", "url": "https://example.com/p/2", "selector": ".price", "target": 359.0},
]
def load_history():
if os.path.exists(WATCH_FILE):
return json.load(open(WATCH_FILE, encoding="utf-8"))
return {}
def save_history(data):
json.dump(data, open(WATCH_FILE, "w", encoding="utf-8"),
ensure_ascii=False, indent=2)
history = load_history()
for p in PRODUCTS:
now = check_price(p["url"], p["selector"])
old = history.get(p["name"])
history[p["name"]] = now
if old is None:
print(p["name"], "已记录价格", now)
elif now < old:
print("降价啦!", p["name"], "从", old, "降到", now)
elif now < p["target"]:
print("到心理价位了:", p["name"], now, "(目标", p["target"], ")")
else:
print(p["name"], "还是", now, ",继续等")
save_history(history)
target 是你心里的"便宜线",低于它就算捡到。下次再跑,程序会拿新价和文件里存的老价比,涨跌一眼看出。
降价了,怎么让你知道
光打印在屏幕上可不行,你总不能一直盯着终端。最简单的是接一个企业微信/钉钉群机器人,降价时直接推消息到手机。
import requests
def notify(msg):
webhook = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的KEY"
requests.post(webhook, json={"msgtype": "text", "text": {"content": msg}})
# 在"降价啦"那个分支里加一句:
# notify(f"{p['name']} 降价了!现在 {now} 元")
把 你的KEY 换成群里机器人给你的地址即可。不想折腾群机器人,也可以改成发邮件(用我们之前讲过的 smtplib),或者先偷懒——把消息写进一个 alerts.txt 文件,睡前瞄一眼也行。
让它每天自动跑,不用你动手
盯着终端跑一次不算完,真正的"哨兵"得自己定时巡逻。装个小库 schedule,让它每天早上九点自动查一轮。
import schedule, time
def patrol():
# 把上面"一次盯一堆"的代码整个塞进这个函数
print("巡逻开始……")
schedule.every().day.at("09:00").do(patrol)
while True:
schedule.run_pending()
time.sleep(60)
time.sleep(60) 是让程序每 60 秒看一眼"到点没",轻量不占资源。想更稳,也可以把它丢进服务器的定时任务里常驻。咱之前聊过的 cron、Docker,这时候就能派上用场了。
新手容易踩的几个坑
- 选择器失效:页面改版后 class 名可能变,报错就回去重新"检查"抄一个新的。
- 价格带逗号或"券后":正则只抓第一串数字,遇到"¥1,299"会拿到 1,记得先清掉逗号,或换更准的提取规则。
- 网站反爬:频繁访问可能被拦,加 time.sleep(3) 放慢节奏,别把人家服务器搞崩。
- 后台浏览器报错:确认 playwright install chromium 装好了,公司电脑若有代理也可能连不上。
小结
你看,一个"盯价助手"其实就是打开网页、读数字、比大小、再喊你一声——每一步都不难,拼起来却真能省下不少冤枉钱。RPA 把"人工刷新"变成"机器巡逻",监控告警思想让它在关键时刻提醒你,这正是自动化最迷人的地方。先从一个商品试起,跑通了再慢慢加。你最想用这个小哨兵盯哪样东西?评论区告诉我,下期挑一个真实链接带大家手把手跑一遍。