×

api 数据挖掘

Open‑Claw 实战|无需逆向,快速搭建电商商品监控与数据分析系统

admin admin 发表于2026-09-07 16:12:53 浏览8 评论0

抢沙发发表评论

前言

做电商运营、竞品调研、比价选品的时候,我们经常需要持续跟进商品的售价、原价、库存、规格、店铺信息。依靠手动刷新页面复制表格,不仅耗时费力,大促期间价格频繁变动,人工根本跟不上节奏。

很多开发者尝试直接解析网页源码,却踩了一堆坑:网页动态渲染、页面改版后代码直接失效、访问频率高就触发风控拦截,想要完整拿到多规格 SKU、店铺信息、原始标价,往往要耗费大量时间做逆向调试。

今天分享一套落地实践,借助 Open‑Claw 的工具能力,避开复杂逆向工作,快速完成商品信息定时采集、数据持久化存储,实现监控告警与基础数据分析,把整个流程从数据获取、存储到分析完整跑通。

一、业务目标梳理

我们这套小系统要实现 3 个核心能力:

  1. 获取商品完整资料:拿到商品标题、现价、原始标价、库存、多规格 SKU、店铺名称、主图、发货地等全部信息。

  2. 定时持续监控:周期性巡检商品,保存每一轮价格、库存快照,捕捉调价、缺货、规格变更事件。

  3. 本地数据分析:读取历史采集记录,做价格波动统计,当出现价格暴跌、库存清零时输出告警提示。

说明:本案例以京东商品作为演示对象,只做学习研究,实际使用请遵守平台相关规则。

二、整体实现思路

传统网页采集会把大量精力消耗在页面 DOM 解析、反爬对抗上。Open‑Claw 相当于一个数据中转助手,我们只需要传入商品编号,就可以拿到结构化整理好的商品资料,不受页面改版影响。

整体流程:

  1. 配置身份凭证,准备待监控的商品编号列表;

  2. 封装数据获取函数,拿到结构化商品原始数据;

  3. 将每次采集结果写入本地 JSON 文件,作为历史快照;

  4. 循环定时执行采集,对比前后快照,识别价格、库存异动;

  5. 读取本地历史文件,完成简单统计分析,输出告警。

三、完整 Python 代码实现

3.1 依赖安装

只需要安装网络请求库,执行下面命令:

pip install requests

3.2 完整源码

import requests
import json
import time
import os
from datetime import datetime

# --------------------------配置区,请修改这里--------------------------
# 你的身份凭证
ACCESS_KEY = "your_access_key"
ACCESS_SECRET = "your_access_secret"
# 需要监控的商品ID列表,可以填多个
MONITOR_ITEM_IDS = ["10335871600"]
# 监控轮询间隔,单位秒,不要设置过小,避免访问过于频繁
MONITOR_INTERVAL = 60 * 30
# 本地快照存储目录
SNAPSHOT_DIR = "./product_snapshot"
# ----------------------------------------------------------------------

def init_dir():
    """初始化存储目录"""
    if not os.path.exists(SNAPSHOT_DIR):
        os.makedirs(SNAPSHOT_DIR)

def fetch_product_raw_data(item_id: str):
    """
    通过Open‑Claw工具获取商品原始结构化数据
    :param item_id: 商品编号
    :return: dict 商品原始字典,失败返回None
    """
    base_url = "这里填入你的访问地址"
    params = {
        "key": ACCESS_KEY,
        "secret": ACCESS_SECRET,
        "num_iid": item_id
    }
    headers = {
        "Accept‑Encoding": "gzip",
        "Connection": "close"
    }
    try:
        resp = requests.get(base_url, params=params, headers=headers, timeout=15)
        resp.raise_for_status()
        result = resp.json()
        # 判断返回状态
        if result.get("error_code") != "0000":
            print(f"【获取失败】商品 {item_id} ,原因:{result.get('reason','未知错误')}")
            return None
        item_data = result.get("item")
        if not item_data:
            print(f"【警告】商品 {item_id} 返回数据为空")
            return None
        return item_data
    except Exception as e:
        print(f"【网络异常】item_id:{item_id},异常信息:{str(e)}")
        return None

def save_snapshot(item_id: str, data: dict):
    """保存一次采集快照到本地文件"""
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    item_folder = os.path.join(SNAPSHOT_DIR, item_id)
    if not os.path.exists(item_folder):
        os.makedirs(item_folder)
    save_path = os.path.join(item_folder, f"snap_{timestamp}.json")
    with open(save_path, "w", encoding="utf‑8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)
    print(f"✅已保存快照:{save_path}")

def get_last_snapshot(item_id: str):
    """读取该商品上一次的快照,用于对比变化"""
    item_folder = os.path.join(SNAPSHOT_DIR, item_id)
    if not os.path.exists(item_folder):
        return None
    file_list = sorted(os.listdir(item_folder))
    if len(file_list) == 0:
        return None
    last_file = file_list[-1]
    full_path = os.path.join(item_folder, last_file)
    with open(full_path, "r", encoding="utf‑8") as f:
        return json.load(f)

def detect_change(old: dict, new: dict):
    """对比新旧快照,检测价格、库存变化,输出告警信息"""
    alert_msg = []
    old_price = float(old.get("price", 0) or 0)
    new_price = float(new.get("price", 0) or 0)
    old_stock = int(old.get("num", 0) or 0)
    new_stock = int(new.get("num", 0) or 0)
    title = new.get("title", "未知商品")

    # 价格变动检测
    if new_price != old_price and new_price > 0:
        alert_msg.append(f"【价格变动】{title} 旧价:{old_price} → 新价:{new_price}")
    # 库存变动检测
    if new_stock != old_stock:
        if new_stock <= 0:
            alert_msg.append(f"⚠️【库存告警】{title} 商品已经缺货!库存:{new_stock}")
        else:
            alert_msg.append(f"【库存变动】{title} 旧库存:{old_stock} → 新库存:{new_stock}")
    for msg in alert_msg:
        print(msg)
    return alert_msg

def analysis_history(item_id: str):
    """简单数据分析:读取历史快照,输出价格最高最低、历史记录条数"""
    item_folder = os.path.join(SNAPSHOT_DIR, item_id)
    if not os.path.exists(item_folder):
        print(f"商品 {item_id} 暂无历史快照数据")
        return
    file_list = sorted(os.listdir(item_folder))
    price_list = []
    for fname in file_list:
        fp = os.path.join(item_folder, fname)
        with open(fp, "r", encoding="utf‑8") as f:
            d = json.load(f)
        p = float(d.get("price",0) or 0)
        if p>0:
            price_list.append(p)
    if len(price_list) == 0:
        print("没有有效价格记录")
        return
    print("\n====历史数据分析结果====")
    print(f"商品ID:{item_id}")
    print(f"采集快照总条数:{len(file_list)}")
    print(f"历史最高价格:{max(price_list)}")
    print(f"历史最低价格:{min(price_list)}")
    print(f"价格均值:{round(sum(price_list)/len(price_list),2)}")
    print("========================\n")

def monitor_loop():
    init_dir()
    print("🛰️商品监控程序启动...")
    while True:
        for item_id in MONITOR_ITEM_IDS:
            new_data = fetch_product_raw_data(item_id)
            if new_data is None:
                continue
            save_snapshot(item_id, new_data)
            old_data = get_last_snapshot(item_id)
            if old_data is not None:
                detect_change(old_data, new_data)
        # 每轮结束之后做一次数据分析
        for item_id in MONITOR_ITEM_IDS:
            analysis_history(item_id)
        print(f"\n本轮巡检完成,等待 {MONITOR_INTERVAL} 秒进入下一轮\n")
        time.sleep(MONITOR_INTERVAL)

if __name__ == "__main__":
    monitor_loop()

四、代码解读与使用说明

  1. 配置区域:修改最上方配置,填入你的凭证、需要监控的商品编号,调整轮询间隔,间隔不要设置过小,避免频繁请求。

  2. 快照存储:每次采集的完整原始数据会保存到product_snapshot文件夹,每个商品单独一个子目录,方便后续回溯。

  3. 异动检测逻辑:对比上一轮快照,识别价格涨跌、库存清零,直接在控制台打印告警;你可以扩展代码,对接邮件、企业微信机器人,实现消息推送。

  4. 数据分析模块:读取本地全部历史快照,统计最高、最低、平均价格,完成简单的趋势分析。

注意:示例中的访问地址需要替换为你实际拿到的访问地址,ACCESS_KEY、ACCESS_SECRET 替换为你自己的凭证。

五、拓展方向

拿到结构化数据之后,我们可以继续做很多拓展:

  1. 存入数据库:把快照写入 SQLite / MySQL,替代本地 JSON 文件,方便做大规模统计。

  2. 可视化图表:结合 pandas + matplotlib,绘制价格随时间变化折线图,直观看到大促期间价格波动。

  3. 多商品批量监控:维护一份商品清单文件,批量读取,同时监控几十上百个竞品。

  4. 消息通知:当检测到降价、缺货,调用企业微信 / 钉钉 / 邮件接口,把告警推送出来。

六、踩坑记录

  1. 轮询间隔不要太小:频繁访问会触发限流,建议至少间隔 15 分钟以上。

  2. 价格偶尔返回异常:业务返回的价格字段存在偶尔不准的情况,做分析时可以增加过滤逻辑,过滤 0 或者异常离谱的数值。

  3. 商品下架情况:当商品下架,会返回对应错误提示,代码里已经做了捕获,可以自行扩展下架告警。

七、写在最后

这套方案最大的好处,就是我们不用再耗费大量精力处理网页动态渲染、页面改版、反爬拦截的问题,把重心放在业务逻辑:监控、对比、分析、告警。


少长咸集

群贤毕至

访客