适用场景:竞品盯价、自有商品库存巡检、大促价格异动捕捉、历史价格统计分析;Python 实现,开箱即用,适合电商运营、数据分析、后端开发同学参考。
前言
做电商或者做比价分析,很多人都有这样的痛点: 需要持续关注几十款商品的价格、库存、规格变动。如果靠人工打开网页,复制粘贴到 Excel,不仅耗费大量时间,还很容易错过大促的降价、库存告急等关键信号。
自己写页面解析脚本,又会遇到平台反访问限制、页面改版解析失效、动态数据渲染等一堆麻烦,调试成本很高。
最近体验了 Open Claw 这套工具,能够稳定拿到商品完整结构化信息,不需要处理网页解析,我们可以专注业务逻辑,快速实现一套监控 + 数据分析的本地程序。本文完整带你从零实现,包含数据持久化、异动告警、历史数据统计分析全部代码。
说明:本文仅采集电商公开展示的商品公开信息,请勿高频频繁轮询,遵守平台相关规范。
整体实现思路
获取商品结构化原始数据(标题、售价、原价、库存、规格 SKU、店铺信息等)
SQLite 本地存储每一次采集记录,留存历史时序数据
定时轮询对比新旧数据,识别价格下跌、库存变化,控制台输出告警提示(可扩展钉钉 / 企业微信推送)
读取本地历史库,做数据分析:历史最高价、最低价、平均售价、价格波动情况
支持批量监控多款商品
环境准备
需要安装依赖库
拿到 Open Claw 的两组凭证,填入代码配置区即可。
完整代码实现
import requests
import sqlite3
import time
from datetime import datetime
from apscheduler.schedulers.background import BackgroundScheduler
# ========================【配置区域,请自行修改】========================
CLAW_KEY = "替换成你的凭证key"
CLAW_SECRET = "替换成你的凭证secret"
# 需要监控的商品编号列表,可以批量添加多个商品
MONITOR_GOODS = ["10335871600", "10057467958584"]
POLL_INTERVAL = 300 # 监控轮询间隔,单位秒,建议最低不要低于300秒
PRICE_DROP_ALERT_RATIO = 0.15 # 降价幅度超过15%触发告警
# =====================================================================
# 初始化数据库,创建数据表
def init_db():
conn = sqlite3.connect("goods_monitor.db")
cur = conn.cursor()
cur.execute('''
CREATE TABLE IF NOT EXISTS goods_record (
id INTEGER PRIMARY KEY AUTOINCREMENT,
goods_id TEXT NOT NULL,
title TEXT,
price REAL,
original_price REAL,
stock INTEGER,
shop_name TEXT,
crawl_time TEXT
)
''')
conn.commit()
conn.close()
# 获取商品详情原始结构化数据
def get_goods_data(goods_id: str):
params = {
"key": CLAW_KEY,
"secret": CLAW_SECRET,
"num_iid": goods_id,
"result_type": "json",
"cache": "yes"
}
try:
resp = requests.get("https://api-gw.onebound.cn/jd/item_get_pro", params=params, timeout=15)
res_json = resp.json()
if res_json.get("error_code") != "0000":
print(f"商品 {goods_id} 获取数据异常:{res_json.get('reason','未知错误')}")
return None
item = res_json.get("item")
if not item:
print(f"商品 {goods_id} 返回数据为空")
return None
data = {
"goods_id": goods_id,
"title": item.get("title", ""),
"price": float(item.get("price", 0)) if item.get("price") else 0,
"original_price": float(item.get("orginal_price",0)) if item.get("orginal_price") else 0,
"stock": int(item.get("num", 0)) if item.get("num") else 0,
"shop_name": item.get("seller_info", {}).get("shop_name", ""),
"crawl_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
return data
except Exception as e:
print(f"网络请求异常 goods_id:{goods_id}, 异常信息:{str(e)}")
return None
# 将本次采集结果存入数据库
def save_to_db(data):
conn = sqlite3.connect("goods_monitor.db")
cur = conn.cursor()
cur.execute('''
INSERT INTO goods_record(goods_id,title,price,original_price,stock,shop_name,crawl_time)
VALUES (?,?,?,?,?,?,?)
''',(
data["goods_id"],
data["title"],
data["price"],
data["original_price"],
data["stock"],
data["shop_name"],
data["crawl_time"]
))
conn.commit()
conn.close()
# 获取这个商品上一次采集的记录,用于对比异动
def get_last_record(goods_id):
conn = sqlite3.connect("goods_monitor.db")
cur = conn.cursor()
cur.execute('''
SELECT price,stock FROM goods_record WHERE goods_id = ? ORDER BY id DESC LIMIT 1
''',(goods_id,))
row = cur.fetchone()
conn.close()
if row:
return {"last_price": row[0], "last_stock": row[1]}
return None
# 监控单款商品,检测价格、库存变动告警
def monitor_one_goods(goods_id):
print(f"\n===== 开始采集商品:{goods_id} =====")
curr_data = get_goods_data(goods_id)
if curr_data is None:
return
save_to_db(curr_data)
last_info = get_last_record(goods_id)
print(f"【{curr_data['title']}】 当前售价:{curr_data['price']},库存:{curr_data['stock']}")
# 第一次采集,没有历史记录,只存储不告警
if last_info is None:
print("首次采集,无历史对比数据")
return
last_price = last_info["last_price"]
last_stock = last_info["last_stock"]
# 价格下降告警
if curr_data["price"] < last_price:
drop_rate = (last_price - curr_data["price"]) / last_price
if drop_rate >= PRICE_DROP_ALERT_RATIO:
print(f"🔔【价格大幅下降告警】原价格{last_price} → 当前{curr_data['price']},降幅{round(drop_rate*100,2)}%")
# 库存清零告警
if curr_data["stock"] == 0 and last_stock > 0:
print(f"⚠️【库存告急告警】商品已经售罄!上一轮库存:{last_stock}")
# 补货提醒
if curr_data["stock"] > 0 and last_stock == 0:
print(f"✅【补货通知】商品恢复库存,当前库存 {curr_data['stock']}")
# 历史数据分析:读取数据库,输出商品价格统计
def analysis_goods_history(goods_id):
"""输出商品历史价格统计:最高、最低、平均价格"""
conn = sqlite3.connect("goods_monitor.db")
cur = conn.cursor()
cur.execute('''
SELECT price,crawl_time FROM goods_record WHERE goods_id = ? ORDER BY crawl_time ASC
''', (goods_id,))
rows = cur.fetchall()
conn.close()
if len(rows) < 2:
print(f"\n商品{goods_id}历史数据不足,暂时无法分析,多跑几次采集后再来")
return
price_list = [r[0] for r in rows]
max_p = max(price_list)
min_p = min(price_list)
avg_p = round(sum(price_list)/len(price_list),2)
first_time = rows[0][1]
last_time = rows[-1][1]
print("\n====================历史数据分析报告====================")
print(f"商品编号:{goods_id}")
print(f"统计时间区间:{first_time} ~ {last_time}")
print(f"历史最高售价:{max_p}")
print(f"历史最低售价:{min_p}")
print(f"历史平均售价:{avg_p}")
print("========================================================")
# 定时任务执行入口
def monitor_task():
for gid in MONITOR_GOODS:
monitor_one_goods(gid)
# 可选:每轮监控完成后,对第一个商品输出统计报告
analysis_goods_history(MONITOR_GOODS[0])
if __name__ == "__main__":
init_db()
scheduler = BackgroundScheduler()
scheduler.add_job(monitor_task, "interval", seconds=POLL_INTERVAL)
print(f"监控程序已启动,监控商品列表:{MONITOR_GOODS},轮询间隔 {POLL_INTERVAL} 秒")
print("Ctrl+C 停止程序\n")
scheduler.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
scheduler.shutdown()
print("\n程序正常退出")代码功能拆解
1、数据库初始化 init_db
创建本地 sqlite 文件,存储每一次采集的:商品 ID、标题、价格、原价、库存、店铺、采集时间。程序重启不会丢失历史记录。
2、get_goods_data 获取结构化商品信息
调用工具拿到完整商品信息,做简单字段提取,把我们关心的价格、库存、店铺信息整理出来。如果返回异常会打印日志。
3、monitor_one_goods 单商品监控逻辑
获取最新数据存入数据库
查询上一轮采集记录,做对比
识别降价、售罄、补货事件,控制台输出告警提示。
拓展思路:你可以把告警部分改成调用钉钉、企业微信 webhook,实现消息推送。
4、analysis_goods_history 历史数据分析
读取本地存储的时序数据,计算最高价、最低价、平均价格,帮我们判断当前价位是否适合入手,也可以用来分析竞品大促的定价规律。
5、定时调度
使用 APScheduler 后台定时任务,每隔设定的时间自动跑一轮全部商品监控。
使用注意事项
轮询间隔不要设置过小,建议最少 300 秒(5 分钟)以上,避免频繁请求。
凭证需要自行替换,没有凭证无法运行。
价格字段存在一定波动偏差,适合做趋势监控,不要当做 100% 精确交易价格。
程序运行后会生成 goods_monitor.db 文件,这就是你的本地数据库,不要随意删除。
如果需要导出 Excel,可以基于读取数据库后的结果,用 pandas 输出 csv 文件。
进阶拓展方向
消息推送:告警逻辑对接钉钉机器人、企业微信,价格变动直接手机收到通知。
SKU 维度监控:代码中可以扩展解析不同规格的价格,监控不同颜色尺码的价格变化。
可视化图表:把历史数据读出来,用 matplotlib 绘制价格趋势折线图。
Web 后台:结合 Flask/FastAPI,做简单网页,查看监控列表、历史图表。
部署到服务器:把脚本部署在云服务器,7×24 小时不间断监控。
小结
借助 Open Claw,我们不需要耗费大量精力去处理网页解析、反访问限制,直接拿到规整的商品数据,把精力聚焦业务逻辑。几十行代码,就实现了一套完整的商品监控 + 数据分析工具,对于电商运营、个人比价都很实用。