×

告别人工盯品!借助 Open‑Claw 快速搭建电商商品全自动监控与数据分析系统(完整实操代码)

admin admin 发表于2026-09-08 17:58:57 浏览6 评论0

抢沙发发表评论

前言

做电商运营、选品分析或者做比价工具,相信大家都遇到过这样的痛点:

  • 需要持续关注多款竞品,价格、库存、规格一变,只能手动刷新页面,人力成本高,很容易错过调价节点;

  • 自己写页面解析脚本,平台防护多,经常遇到访问限制;平台页面稍微改版,整个解析逻辑直接失效,维护成本很高;

  • 拿到零散数据之后,缺少统一存储,无法回溯历史价格,很难做价格波动、库存变化的趋势分析;

  • 多规格商品,不同型号的价格、库存分散在页面各处,很难一次性把全部规格信息完整收集。

之前我尝试过浏览器自动化、页面解析脚本,都要花大量精力处理反限制、页面改版适配。后来使用 Open‑Claw 这套工具,只需要传入商品编号,就可以拿到标准化结构化商品数据,几十行代码就搭建起 7×24 小时自动监控、本地存储、异动识别、简单数据分析的完整体系,不用再关心页面布局变化。

本篇文章完整分享整套落地流程:工具准备、数据获取、定时轮询监控、异常判断、本地持久化存储、基础数据分析,附带可直接运行 Python 源码。

提示:本文仅用于学习公开商品公开信息,业务使用请遵守平台相关规则。

整体方案思路

整套系统拆分为 4 个简单模块:

  1. 数据获取模块:输入商品编号,获取商品标题、现价、原价、库存、全部规格、店铺信息等结构化数据;

  2. 定时监控模块:循环定时执行,周期性采集商品快照;

  3. 异动检测模块:对比上一次记录,识别价格下跌、库存清零、规格变动等异常;

  4. 数据存储 & 分析模块:把每一次采集结果保存到本地文件,基于历史记录做简单统计分析。

不需要去解析网页 DOM,不用处理各种页面加密、动态渲染的问题,工具已经帮我们处理好底层的页面访问与内容提取,我们只需要专注业务逻辑。

前期准备

  1. 安装依赖库

pip install requests pandas apscheduler
  • requests:网络请求

  • pandas:数据存储与简单统计分析

  • apscheduler:实现定时任务

2.准备好工具的凭证信息,获取keysecret两个凭证字符串,拿到需要监控的商品编号。

完整 Python 代码实现

import requests
import json
import time
import csv
from datetime import datetime
import pandas as pd
from apscheduler.schedulers.background import BackgroundScheduler

# --------------------------配置区,请修改为你自己的信息--------------------------
KEY = "你的key字符串"
SECRET = "你的secret字符串"
MONITOR_GOODS_ID_LIST = ["10335871600"]  # 需要监控的商品编号列表
MONITOR_INTERVAL_MINUTE = 30  # 监控间隔,单位分钟
WARNING_PRICE_THRESHOLD = 50  # 价格低于该数值触发简单告警
SAVE_CSV_PATH = "./goods_monitor_record.csv"
# --------------------------------------------------------------------------------

class GoodsMonitor:
    def __init__(self):
        self.history_data = {}

    def fetch_goods_info(self, goods_id):
        """获取商品结构化数据"""
        base_url = "https://api-gw.onebound.cn/jd/item_get_pro"
        params = {
            "key": KEY,
            "secret": SECRET,
            "num_iid": goods_id,
            "cache": "no",
            "result_type": "json"
        }
        try:
            resp = requests.get(base_url, params=params, timeout=15)
            raw_json = resp.json()
        except Exception as e:
            print(f"【网络异常】商品 {goods_id} 获取失败,异常:{str(e)}")
            return None

        error_code = raw_json.get("error_code", "")
        if error_code != "0000":
            err_msg = raw_json.get("error", "未知错误")
            print(f"【业务异常】商品 {goods_id} 读取失败,信息:{err_msg}")
            return None

        item = raw_json.get("item", {})
        if not item:
            print(f"【警告】商品 {goods_id} 未返回有效主体数据")
            return None

        sku_list = item.get("skus", {}).get("sku", [])
        parse_result = {
            "snapshot_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "goods_id": item.get("num_iid", ""),
            "title": item.get("title", ""),
            "current_price": float(item.get("price", 0)) if item.get("price") else 0.0,
            "origin_price": float(item.get("orginal_price", 0)) if item.get("orginal_price") else 0.0,
            "stock_total": item.get("num", 0),
            "shop_name": item.get("seller_info", {}).get("shop_name", ""),
            "sku_count": len(sku_list),
            "sku_detail": sku_list
        }
        return parse_result

    def detect_change(self, new_data):
        """对比历史快照,识别价格、库存异动"""
        goods_id = new_data["goods_id"]
        if goods_id not in self.history_data:
            self.history_data[goods_id] = new_data
            return []

        old = self.history_data[goods_id]
        alert_list = []
        # 价格下跌告警
        if new_data["current_price"] < old["current_price"]:
            alert_list.append(f"价格变动:由{old['current_price']} 降到 {new_data['current_price']}")
        # 库存归零告警
        if old["stock_total"] > 0 and new_data["stock_total"] == 0:
            alert_list.append("库存告警:商品变为无货状态")
        # 自定义阈值告警
        if new_data["current_price"] < WARNING_PRICE_THRESHOLD:
            alert_list.append(f"阈值告警:当前价格 {new_data['current_price']} 低于预设阈值 {WARNING_PRICE_THRESHOLD}")

        self.history_data[goods_id] = new_data
        return alert_list

    def save_to_csv(self, data):
        """保存本次快照到csv文件,留存历史记录"""
        headers = ["snapshot_time", "goods_id", "title", "current_price", "origin_price", "stock_total", "shop_name", "sku_count"]
        row = [
            data["snapshot_time"],
            data["goods_id"],
            data["title"],
            data["current_price"],
            data["origin_price"],
            data["stock_total"],
            data["shop_name"],
            data["sku_count"]
        ]
        file_exist = False
        try:
            with open(SAVE_CSV_PATH, "r", encoding="utf‑8") as f:
                file_exist = True
        except FileNotFoundError:
            pass

        with open(SAVE_CSV_PATH, "a", newline="", encoding="utf‑8") as f:
            writer = csv.writer(f)
            if not file_exist:
                writer.writerow(headers)
            writer.writerow(row)

    def run_single_task(self):
        """单次监控任务执行入口"""
        print(f"\n====== 开始执行一轮监控 {datetime.now().strftime('%Y‑%m‑%d %H:%M:%S')} ======")
        for gid in MONITOR_GOODS_ID_LIST:
            info = self.fetch_goods_info(gid)
            if not info:
                continue
            print(f"商品:{info['title']}|现价:{info['current_price']}|库存:{info['stock_total']}")
            alerts = self.detect_change(info)
            if alerts:
                print("‼️ 检测到异动:")
                for a in alerts:
                    print(f"\t‑ {a}")
            self.save_to_csv(info)
            time.sleep(1)

def analysis_history():
    """简单数据分析:读取本地csv,输出统计信息"""
    try:
        df = pd.read_csv(SAVE_CSV_PATH, encoding="utf‑8")
        if df.empty:
            print("暂无历史监控记录")
            return
        print("\n========历史数据简单分析结果========")
        for goods_id in df["goods_id"].unique():
            sub_df = df[df["goods_id"] == goods_id]
            print(f"\n商品编号:{goods_id}")
            print(f"记录采样次数:{len(sub_df)}")
            print(f"历史最低价格:{sub_df['current_price'].min()}")
            print(f"历史最高价格:{sub_df['current_price'].max()}")
            print(f"价格均值:{round(sub_df['current_price'].mean(),2)}")
    except FileNotFoundError:
        print("还没有生成监控记录文件,请先运行监控任务")

if __name__ == "__main__":
    monitor = GoodsMonitor()
    # 执行一次
    monitor.run_single_task()

    # 开启后台定时任务
    scheduler = BackgroundScheduler()
    scheduler.add_job(monitor.run_single_task, "interval", minutes=MONITOR_INTERVAL_MINUTE)
    scheduler.start()
    print(f"定时监控已启动,每 {MONITOR_INTERVAL_MINUTE} 分钟执行一次,按 Ctrl+C 停止")
    try:
        while True:
            time.sleep(60)
    except KeyboardInterrupt:
        scheduler.shutdown()
        print("\n定时任务已停止,正在输出历史数据分析")
        analysis_history()

代码说明与运行效果

  1. 修改配置区:填入你的凭证,填写需要监控的商品编号,设置监控间隔、告警价格阈值。

  2. 运行脚本,程序会先执行一次采集,之后后台定时循环采集;

  3. 每一轮采集完成,自动把快照写入本地goods_monitor_record.csv

  4. 如果检测到降价、库存清零、低于预设阈值,控制台打印告警信息;

  5. Ctrl+C 终止程序后,自动读取本地历史文件,输出简单统计(最高、最低、平均价格)。

返回的数据里面还包含完整 SKU 规格数组,你可以扩展代码,把每个规格的价格、库存一并写入文件,实现多规格维度监控。

常见踩坑点

  1. 返回价格不准:部分场景下返回的主商品价格存在偏差,优先读取 skus 数组内各个子规格的价格作为基准;

  2. 商品查无结果:确认商品编号正确,商品没有下架;下架商品会返回对应异常提示;

  3. 请求频繁报错:不要设置过小的轮询间隔,业务场景建议至少 10‑30 分钟以上采集一次;

  4. 凭证报错:核对 key、secret 字符串,不要带多余空格换行。

业务拓展方向

基于这套基础脚本,还可以继续扩展能力:

  1. 消息推送:检测异动之后,对接企业微信、钉钉机器人,实现消息推送,不用盯着控制台;

  2. 数据库存储:把 csv 替换为 sqlite/mysql,适合长期大批量商品监控;

  3. 可视化:使用 matplotlib 或者 pyecharts 读取历史记录,画出商品价格走势图;

  4. 批量监控:从 txt/excel 读取上百个商品编号,批量循环监控竞品池;

  5. 规格级监控:遍历 skus 列表,针对每一个子规格独立做价格库存变化判断。

总结

对比传统自己写页面解析的方案,Open‑Claw 工具把页面访问、解析、适配全部封装完成,开发者只需要关注业务逻辑。几十行代码就可以实现 7×24 小时的商品监控,不用再反复调试页面选择器,平台页面改版也几乎不需要修改业务代码,对于中小规模竞品监控、选品数据分析场景非常友好。


群贤毕至

访客