前言
做电商运营、市场调研或者竞品分析的时候,相信很多人都遇到这样的痛点: 想要盯一批竞品商品,手动复制粘贴价格、库存、规格信息到 Excel,耗时又容易出错;大促期间价格频繁变动,等到人工发现调价,机会早就错过了;想要统计一批商品的价格区间、规格分布,手动统计效率极低。
自己写原生页面解析,会碰到层出不穷的反访问限制、页面结构改版、图片路径解析、规格多维度拆解等一堆麻烦问题。页面结构一改,之前写好的解析逻辑就要全部重写,维护成本很高。
最近在使用 Open Claw 这套工具,它封装好了商品信息解析能力,我们只需要传入商品编号,就可以直接拿到结构化的商品信息,把精力全部放在监控逻辑、数据存储、业务分析上,不用耗费大量时间处理页面解析细节。
本文会完整演示:单商品信息获取、定时监控价格库存变动、数据落地存储、简单数据分析,代码可以直接拿来二次改造,适合部署在本地或者服务器做轻量级业务监控。
提示:本教程仅用于学习研究,请遵守对应平台规则,不要高频大规模访问,避免对平台造成压力。
环境准备
运行代码依赖 requests 库,如果还没有安装,执行:
pip install requests pandas
一、获取商品结构化信息
我们只需要准备好自己的**凭证密钥**,传入商品编号,工具会返回整理完毕的数据:标题、售价、原价、库存、规格 SKU、店铺信息、图片地址、发货地等全部字段,不需要自己做 HTML 解析。
示例代码:
# -*- coding:utf-8 -*-
import requests
import json
class GoodsHelper:
def __init__(self, access_key, access_secret):
self.access_key = access_key
self.access_secret = access_secret
self.base_url = "https://api-gw.onebound.cn/jd/item_get_pro"
def get_goods_detail(self, goods_id):
"""获取商品完整结构化信息"""
params = {
"key": self.access_key,
"secret": self.access_secret,
"num_iid": goods_id,
"cache": "no",
"result_type": "json"
}
try:
resp = requests.get(self.base_url, params=params, timeout=20)
result = resp.json()
item_data = result.get("item", {})
return item_data
except Exception as e:
print(f"获取商品异常:{str(e)}")
return None
if __name__ == "__main__":
# 替换成自己的凭证
KEY = "你的key"
SECRET = "你的secret"
helper = GoodsHelper(KEY, SECRET)
goods_info = helper.get_goods_detail("10335871600")
if goods_info:
print("商品标题:", goods_info.get("title"))
print("当前售价:", goods_info.get("price"))
print("原始标价:", goods_info.get("orginal_price"))
print("库存:", goods_info.get("num"))
print("店铺名称:", goods_info.get("seller_info", {}).get("shop_name"))
print("商品链接:", goods_info.get("detail_url"))
# 获取多规格信息
sku_list = goods_info.get("skus", {}).get("sku", [])
for sku in sku_list:
print(f"规格:{sku.get('properties_name')} | 价格:{sku.get('price')} | sku库存:{sku.get('quantity')}")
运行之后直接输出结构化结果。我们拿到的数据包含:主图集合、多规格 SKU、品牌、发货地、店铺信息等,省去大量解析工作。
二、实现定时监控,捕捉价格、库存变动
最核心的场景:持续监控目标商品,对比上一轮采集结果,价格下调、库存骤变的时候输出告警提示。 可以扩展:告警推送钉钉 / 企业微信、写入本地文件或者数据库持久化。
# -*- coding:utf-8 -*-
import requests
import time
import datetime
import pandas as pd
class GoodsHelper:
def __init__(self, access_key, access_secret):
self.access_key = access_key
self.access_secret = access_secret
self.base_url = "https://api-gw.onebound.cn/jd/item_get_pro"
def get_goods_detail(self, goods_id):
params = {
"key": self.access_key,
"secret": self.access_secret,
"num_iid": goods_id,
"cache": "no",
"result_type": "json"
}
try:
resp = requests.get(self.base_url, params=params, timeout=20)
result = resp.json()
return result.get("item", {})
except Exception as e:
print(f"请求出错:{e}")
return None
class GoodsMonitor:
def __init__(self, helper):
self.helper = helper
self.history = dict() # 保存上一次采集的数据 {goods_id:data}
def monitor_loop(self, goods_id_list, interval=300):
"""
循环监控
:param goods_id_list: 需要监控的商品id数组
:param interval: 轮询间隔,单位秒,示例300=5分钟,不要设置过小
"""
print(f"启动监控任务,监控商品列表:{goods_id_list},轮询间隔 {interval}s")
while True:
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
for gid in goods_id_list:
data = self.helper.get_goods_detail(gid)
if not data:
continue
title = data.get("title")
price = float(data.get("price", 0))
stock = int(data.get("num", 0))
print(f"\n[{now}] 商品:{title[:40]} 价格:{price} 库存:{stock}")
# 判断是否历史存在
if gid not in self.history:
self.history[gid] = {"price": price, "stock": stock}
continue
old = self.history[gid]
# 价格变动告警
if price != old["price"]:
print(f"【价格变动告警】{title} 旧价:{old['price']} → 新价:{price}")
# 库存大幅变动告警
if abs(stock - old["stock"]) > 20:
print(f"【库存异动告警】{title} 旧库存:{old['stock']} → 新库存:{stock}")
# 更新历史记录
self.history[gid]["price"] = price
self.history[gid]["stock"] = stock
time.sleep(interval)
if __name__ == "__main__":
KEY = "你的key"
SECRET = "你的secret"
helper = GoodsHelper(KEY, SECRET)
monitor = GoodsMonitor(helper)
# 设置需要监控的商品编号列表
watch_list = ["10335871600"]
# 启动监控,间隔5分钟
monitor.monitor_loop(watch_list, interval=300)
⚠️注意:轮询间隔不要设置过小,建议最少 3‑5 分钟以上,避免频繁请求。
三、数据落地:保存历史记录到 CSV 做数据分析
采集到的数据不能只打印控制台,我们把每次采集结果写入 csv 文件,后续可以用 pandas 做统计分析,分析价格波动、价格分布区间。
def save_record_to_csv(goods_id, goods_data, csv_path="goods_record.csv"):
"""保存单条采集记录"""
record = {
"crawl_time": datetime.datetime.now().strftime("%Y‑%m‑%d %H:%M:%S"),
"goods_id": goods_id,
"title": goods_data.get("title"),
"price": goods_data.get("price"),
"orginal_price": goods_data.get("orginal_price"),
"stock": goods_data.get("num"),
"shop_name": goods_data.get("seller_info", {}).get("shop_name"),
"location": goods_data.get("location")
}
df_new = pd.DataFrame([record])
try:
df_old = pd.read_csv(csv_path)
df_all = pd.concat([df_old, df_new], ignore_index=True)
except FileNotFoundError:
df_all = df_new
df_all.to_csv(csv_path, index=False, encoding="utf‑8‑sig")
# 简单数据分析示例
def analysis_data(file_path="goods_record.csv"):
df = pd.read_csv(file_path)
print("====基础统计分析====")
print(f"总采集记录条数:{len(df)}")
print(f"价格均值:{df['price'].mean():.2f}")
print(f"价格最高:{df['price'].max()}")
print(f"价格最低:{df['price'].min()}")
print("\n各商品平均价格:")
print(df.groupby("goods_id")["price"].mean())
if __name__ == "__main__":
# 测试写入与分析
KEY = "你的key"
SECRET = "你的secret"
helper = GoodsHelper(KEY, SECRET)
info = helper.get_goods_detail("10335871600")
save_record_to_csv("10335871600", info)
analysis_data()
运行完成之后,本地生成goods_record.csv,里面留存每一次采集快照,后续可以用 Excel 或者 Python 做:价格趋势、大促前后价格对比、竞品价格区间统计等分析工作。
四、业务拓展思路
拿到这套基础能力之后,可以衍生很多实用功能:
- 批量竞品监控:维护一份商品 id 清单,循环批量采集竞品,输出竞品周报;
- 消息告警推送:价格 / 库存变动时调用钉钉、企业微信机器人接口,把告警消息推送到工作群;
- 多规格 SKU 分析:解析返回的 SKU 数组,统计不同规格的定价差异,分析对手的规格定价策略;
- 持久化存储:把 CSV 替换成 MySQL、SQLite 数据库,支持长期海量历史数据存储;
- 简单可视化:借助 matplotlib 绘制价格波动曲线,直观看到一段时间价格走势。
踩坑总结与注意事项
- 不要设置过于频繁的轮询间隔,高频采集不仅会触发限制,也没有实际业务意义;
- 返回的价格为商品展示价格,部分场景下多规格商品每个细分规格真实标价需要读取 sku 列表字段;
- 部分店铺不会返回完整店铺信息,这属于平台返回限制,代码做好空值判断;
- 工具自带缓存开关 cache 参数,如果需要实时最新数据设置
cache:"no";调试的时候可以打开缓存加快响应速度。
总结
Open Claw 最大价值就是帮我们屏蔽了复杂页面解析,不用去处理页面改版、反访问、图片路径、规格拆解等脏活累活。开发者把重心放在监控业务逻辑、数据存储、业务分析,几十行代码就搭建一套可用的商品监控体系。