×

api 数据挖掘

告别人工盯品:借助 Open‑Claw 快速搭建电商商品监控与数据分析体系(附完整 Python 代码)

admin admin 发表于2026-08-27 10:37:03 浏览8 评论0

抢沙发发表评论

前言

做电商运营、选品、竞品调研的时候,相信很多朋友都遇到过这些痛点:

  • 需要持续盯多款竞品,人工反复打开页面查看价格、库存、促销活动,耗费大量时间;

  • 大促期间竞品调价、库存变动节奏很快,人很难做到 7×24 小时实时捕捉变化;

  • 拿到一堆零散的商品信息,很难沉淀历史数据,做价格趋势、SKU 规格对比分析;

  • 直接从网页解析页面,容易遇到访问限制、页面改版导致脚本直接失效,维护成本很高。

之前我尝试过写页面解析脚本,但是平台页面结构经常调整,隔一段时间代码就失效,调试反爬相关逻辑消耗大量精力。后来接触到 Open‑Claw,它可以直接输出结构化标准化的商品全量资料,不需要再折腾页面解析逻辑,我们只需要专注做监控逻辑、数据存储、业务分析,快速搭一套属于自己的商品监测工具。

本篇文章面向开发者、电商从业者,完整讲解从获取商品信息、变化监测、数据存储,再到简单数据分析的整套落地流程,代码可以直接修改配置后运行。

说明:本教程仅做技术学习演示,使用时请遵守对应平台使用规范,合理控制访问频次。

整体实现思路

整套工具分成 4 个核心模块:

  1. 商品信息获取模块:输入商品编号,返回结构化完整商品资料,包含标题、售价、原价、库存、规格、店铺信息、图片等内容;

  2. 变化检测模块:对比上一轮保存的数据,识别价格涨跌、库存变动、规格变更,输出告警提示;

  3. 本地持久化模块:把每一轮采集的数据保存到本地 JSON/CSV,沉淀历史时序数据;

  4. 简易数据分析模块:读取历史记录,做价格波动统计、SKU 规格整理,输出简单统计结果。

环境准备

依赖安装,执行下面命令:

pip install requests pandas

完整可运行代码实现

# coding:utf-8
import requests
import json
import time
import os
import pandas as pd
from datetime import datetime

# ========== 配置区,请修改为你自己的凭证和监控商品 ==========
CLAW_KEY = "填入你的key"
CLAW_SECRET = "填入你的secret"
# 需要监控的商品编号列表
MONITOR_GOODS = ["10335871600", "10057467958584"]
# 循环检测间隔,单位秒,不建议设置过小,示例5分钟轮询一次
MONITOR_INTERVAL = 300
# 降价告警阈值,0.1代表价格下跌超过10%触发提醒
PRICE_DROP_ALERT = 0.1
# 历史数据存储文件
HISTORY_FILE = "goods_history.json"
CSV_EXPORT = "goods_record.csv"
# ==========================================================


def load_last_cache():
    """加载上一轮缓存的商品数据"""
    if os.path.exists(HISTORY_FILE):
        with open(HISTORY_FILE, "r", encoding="utf‑8") as f:
            return json.load(f)
    return {}


def save_cache(data):
    """保存当前采集结果到本地缓存文件"""
    with open(HISTORY_FILE, "w", encoding="utf‑8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)


def fetch_goods_data(goods_id):
    """
    获取单个商品结构化数据
    :param goods_id: 商品数字编号
    :return: 解析完成的商品字典,失败返回None
    """
    base_url = "https://api‑gw.onebound.cn/jd/item_get_pro"
    params = {
        "key": CLAW_KEY,
        "secret": CLAW_SECRET,
        "num_iid": goods_id,
        "result_type": "json",
        "cache": "yes",
        "lang": "cn"
    }
    headers = {
        "Accept‑Encoding": "gzip",
        "Connection": "close"
    }
    try:
        resp = requests.get(base_url, params=params, headers=headers, timeout=20)
        resp_json = resp.json()
        # 判断返回状态,非0000代表异常
        if resp_json.get("error_code") != "0000":
            err_msg = resp_json.get("reason", "未知异常")
            print(f"【获取失败】商品{goods_id},原因:{err_msg}")
            return None
        item_data = resp_json.get("item", {})
        if not item_data:
            print(f"【获取失败】商品{goods_id}返回内容为空")
            return None

        # 提取核心业务字段,做标准化整理
        parse_result = {
            "goods_id": item_data.get("num_iid"),
            "title": item_data.get("title", ""),
            "price": float(item_data.get("price", 0)) if item_data.get("price") else 0.0,
            "original_price": float(item_data.get("orginal_price", 0)) if item_data.get("orginal_price") else 0.0,
            "stock": item_data.get("num", 0),
            "shop_name": item_data.get("seller_info", {}).get("shop_name", ""),
            "detail_url": item_data.get("detail_url", ""),
            "collect_time": datetime.now().strftime("%Y‑%m‑%d %H:%M:%S"),
            "skus": item_data.get("skus", {}).get("sku", [])
        }
        return parse_result
    except Exception as e:
        print(f"【请求异常】商品{goods_id}, 错误:{str(e)}")
        return None


def detect_change(old_data, new_data):
    """对比新旧两份数据,检测价格库存变化,输出告警信息"""
    alert_list = []
    if not old_data:
        alert_list.append("首次采集该商品,无历史对比")
        return alert_list

    old_price = old_data["price"]
    new_price = new_data["price"]
    old_stock = old_data["stock"]
    new_stock = new_data["stock"]

    # 价格变动检测
    if abs(new_price - old_price) > 0.01:
        change_rate = (new_price - old_price) / old_price if old_price > 0 else 0
        if new_price < old_price and abs(change_rate) >= PRICE_DROP_ALERT:
            alert_list.append(f"⚠️降价告警!{old_price} → {new_price},降幅{abs(change_rate)*100:.1f}%")
        elif new_price > old_price:
            alert_list.append(f"📈涨价提醒!{old_price} → {new_price}")
        else:
            alert_list.append(f"💡价格微调:{old_price} → {new_price}")

    # 库存变动检测
    if new_stock != old_stock:
        if new_stock == 0:
            alert_list.append(f"🚨库存告急,商品变为无货!原库存:{old_stock}")
        elif old_stock == 0 and new_stock > 0:
            alert_list.append(f"✅商品补货成功!当前库存 {new_stock}")
        else:
            alert_list.append(f"📦库存变动 {old_stock} → {new_stock}")
    return alert_list


def export_to_csv(all_records):
    """把采集记录导出csv,方便后续做表格分析"""
    rows = []
    for goods_id, records in all_records.items():
        for rec in records:
            rows.append({
                "采集时间": rec["collect_time"],
                "商品ID": rec["goods_id"],
                "商品标题": rec["title"],
                "现价": rec["price"],
                "原价": rec["original_price"],
                "库存": rec["stock"],
                "店铺名称": rec["shop_name"]
            })
    df = pd.DataFrame(rows)
    df.to_csv(CSV_EXPORT, index=False, encoding="utf‑8‑sig")


def simple_analysis():
    """简易数据分析示例:读取csv,统计价格区间、输出基础统计信息"""
    if not os.path.exists(CSV_EXPORT):
        print("暂无导出记录,跳过分析")
        return
    df = pd.read_csv(CSV_EXPORT, encoding="utf‑8‑sig")
    print("\n=====简易数据分析报告=====")
    for gid in df["商品ID"].unique():
        sub_df = df[df["商品ID"] == gid]
        print(f"\n商品ID {gid}:{sub_df.iloc[0]['商品标题'][:30]}...")
        print(f"  采集记录条数:{len(sub_df)}")
        print(f"  历史最低价格:{sub_df['现价'].min()}")
        print(f"  历史最高价格:{sub_df['现价'].max()}")
        print(f"  平均价格:{round(sub_df['现价'].mean(),2)}")


def main_loop():
    print("====商品监控程序启动====")
    cache_data = load_last_cache()
    history_records = {}
    # 初始化历史记录容器
    for gid in MONITOR_GOODS:
        if gid not in history_records:
            history_records[gid] = []

    while True:
        now_time = datetime.now().strftime("%Y‑%m‑%d %H:%M:%S")
        print(f"\n【本轮采集时间】{now_time}")
        for goods_id in MONITOR_GOODS:
            new_item = fetch_goods_data(goods_id)
            if new_item is None:
                continue
            # 保存到全量历史,用于导出报表
            history_records[goods_id].append(new_item)
            old_item = cache_data.get(goods_id)
            alerts = detect_change(old_item, new_item)
            print(f"\n>>商品:{new_item['title'][:40]}")
            for msg in alerts:
                print(f"    {msg}")
            # 更新缓存为当前最新数据
            cache_data[goods_id] = new_item
        # 写入本地缓存文件
        save_cache(cache_data)
        export_to_csv(history_records)
        simple_analysis()
        print(f"\n本轮结束,等待 {MONITOR_INTERVAL} 秒进入下一轮")
        time.sleep(MONITOR_INTERVAL)


if __name__ == "__main__":
    try:
        main_loop()
    except KeyboardInterrupt:
        print("\n程序手动停止,已保存当前数据文件")

代码核心功能讲解

  1. 数据获取函数 fetch_goods_data 不需要解析网页 HTML,直接拿到整理好的结构化结果,提取标题、价格、原价、库存、SKU 规格、店铺、链接等关键字段。返回异常状态做捕获,商品下架、编号错误、权限问题都会打印提示。

  2. 变化检测函数 detect_change 拿上一轮缓存的数据和本轮对比,自动识别涨价、降价(设置阈值,小幅度波动不告警)、缺货、补货,输出告警文本。可以后续扩展,对接企业微信、钉钉消息推送,实现真正消息提醒。

  3. 持久化存储

  • goods_history.json:保存每个商品最新一轮数据,用于下一轮对比;

  • goods_record.csv:每一轮全部历史记录写入表格,用 Excel 打开就可以直接做透视、画图,看价格随时间变化走势。

  1. 简易数据分析 simple_analysis 读取 CSV 历史,对每个商品输出历史最高价、最低价、平均成交价,快速看商品的价格波动区间。

拓展优化方向

1. 消息告警推送

现在告警只打印控制台,可以增加钉钉 / 企业微信 webhook,当检测到降价、缺货的时候,直接推送消息到工作群,不用盯着控制台运行。

2. 数据库存储

小体量用 CSV 完全够用;如果监控几十上百款商品,建议换成 SQLite、MySQL,方便做复杂查询,比如筛选某时间段所有降价商品。

3.SKU 粒度监控

当前示例取商品整体信息,返回结果自带完整 SKU 数组,可以改造代码,针对每一个子规格单独记录价格库存,适合多规格复杂商品的竞品分析。

4. 可视化图表

结合 matplotlib、plotly,读取 CSV 历史数据,自动绘制每个商品价格趋势折线图,直观看到大促前后价格变动轨迹。

5. 任务调度分离

长时间运行可以把采集逻辑做成后台定时任务,不需要一直开着脚本;Linux 环境下可配置 systemd 服务或者 crontab 定时执行。

踩坑记录与注意事项

  1. 轮询间隔不要设置过小,短时间高频访问会触发限流,建议至少间隔 3‑5 分钟以上;

  2. 部分商品多规格场景,整体展示价格和子 SKU 实际售价存在差异,做精细分析时,优先读取 SKU 数组内部对应规格的价格;

  3. 部分自营、第三方店铺,店铺相关字段不一定全部返回,代码已经做了空值兼容;

  4. 遇到商品下架,返回结果会提示商品未找到,脚本会捕获异常不会直接崩溃;

  5. 凭证信息不要硬编码提交到公开代码仓库,生产环境建议放到环境变量读取。

业务场景可以怎么用

  1. 竞品监控:跟踪竞品多款商品,记录调价节奏、大促降价幅度,给自己的定价、促销活动做参考;

  2. 采购备货参考:持续看竞品库存变动,辅助判断市场热度,辅助备货决策;

  3. 个人好物蹲价:想要买的商品,设置降价阈值,一旦低于心理价位立刻收到提醒;

  4. 选品分析:批量收集一批候选商品历史价格、规格,筛选性价比高的目标单品。

写在最后

这套方案最大的优势,是不用投入精力维护页面解析逻辑,把重心放在业务逻辑上。Open‑Claw 帮我们处理了页面各种复杂解析工作,输出规整结构化数据,开发者可以快速把精力投入监控告警、历史统计、数据分析业务。

上面这份代码可以直接跑通,只需要填入自己的凭证,填写需要监控的商品编号,就可以立刻拥有一套属于自己的商品监测工具。后续可以基于这个基础,按需扩展推送、数据库、可视化等功能。


少长咸集

群贤毕至

访客