×

api 数据挖掘

从 0 搭建电商竞品全自动监控 & 数据分析系统,解放运营 90% 重复工作

admin admin 发表于2026-08-13 17:19:09 浏览7 评论0

抢沙发发表评论

前言

做电商运营、产品投放、市场调研的朋友,几乎都有同一个痛点:需要每天手动翻看竞品商品,记录价格、库存、活动、规格变化,一旦赶上大促、上新调价,光是盯十几款竞品就要耗费大半天。

传统手动记录不仅效率极低,还很容易遗漏关键变动;直接写浏览器自动化抓取又会频繁触发平台风控,IP 封禁、页面解析失效、动态渲染数据缺失等问题层出不穷。

今天分享一套稳定、轻量化的自动化数据方案,借助 OpenClaw 标准化数据能力,无需复杂反爬适配,几行代码就能完成商品全维度数据定时采集、存储、异动预警与数据分析,适配京东全品类商品,小白也能直接落地部署。

一、方案整体架构设计

整套系统分为四层,低耦合易维护,可根据业务需求按需扩展:

  1. 数据采集层:定时拉取商品标准化结构化数据,涵盖标题、原价、售价、多规格 SKU、库存、品牌、发货地、商品图、销量、店铺信息等全字段;

  2. 数据持久层:采用本地 CSV / 轻量数据库存储历史时序数据,留存每一次抓取的价格、库存快照;

  3. 异动分析层:对比历史数据,识别降价、涨价、库存清零、新增促销规格等异常变动;

  4. 输出应用层:自动生成价格趋势报表、竞品对比清单,异动实时打印告警,可拓展企业微信 / 邮件推送。

方案核心优势

  1. 零反爬适配:不用处理 UA、Cookie、代理池,无需解析复杂动态页面,返回干净结构化 JSON;

  2. 字段全覆盖:一次性拿到商品基础信息、多规格 SKU、店铺详情、主图详情图、物流费用;

  3. 稳定低延迟:内置缓存机制,重复监控同一商品大幅缩短响应耗时;

  4. 多语言兼容:Python/Java/Go/NodeJS 等主流开发语言均有成熟调用逻辑;

  5. 轻量化部署:单脚本即可运行,无需搭建分布式集群,个人、小微企业均可使用。

二、前置环境准备

1. 依赖安装(Python 版本)

# 核心请求库
pip install requests pandas apscheduler python-dotenv
  • requests:网络请求获取商品数据

  • pandas:数据存储、导出报表、时序分析

  • apscheduler:定时任务,实现 7×24 小时自动监控

  • python-dotenv:安全存储凭证,避免硬编码密钥

2. 凭证配置规范

在项目根目录新建.env文件,填入专属凭证(保密不提交代码仓库)

# 个人访问凭证
ACCESS_KEY=你的专属key
ACCESS_SECRET=你的专属secret
# 需要监控的商品ID,多个用英文逗号分隔
MONITOR_ITEM_IDS=10335871600,10057467958584
# 监控周期,单位分钟
MONITOR_INTERVAL=30
# 价格异动预警阈值,单位元
PRICE_ALERT_THRESHOLD=5

三、完整可运行实战代码

3.1 核心数据采集封装类(core_monitor.py)

import os
import json
import time
import requests
import pandas as pd
from dotenv import load_dotenv
from datetime import datetime
from apscheduler.schedulers.background import BackgroundScheduler

# 加载环境变量
load_dotenv()

class EcomProductMonitor:
    def __init__(self):
        # 读取凭证与配置
        self.key = os.getenv("ACCESS_KEY")
        self.secret = os.getenv("ACCESS_SECRET")
        self.item_ids = os.getenv("MONITOR_ITEM_IDS").split(",")
        self.alert_threshold = float(os.getenv("PRICE_ALERT_THRESHOLD"))
        self.monitor_interval = int(os.getenv("MONITOR_INTERVAL"))
        
        # 存储历史数据文件
        self.data_file = "product_history.csv"
        self.init_data_file()

    def init_data_file(self):
        """初始化存储表格,不存在则创建表头"""
        if not os.path.exists(self.data_file):
            columns = [
                "crawl_time", "item_id", "title", "brand", "current_price",
                "original_price", "stock_num", "sales", "shop_name", "sku_list"
            ]
            pd.DataFrame(columns=columns).to_csv(self.data_file, index=False, encoding="utf-8-sig")

    def fetch_product_data(self, item_id):
        """拉取单款商品完整结构化数据"""
        base_url = "https://api-gw.data-gateway.cn/jd/item_detail"
        params = {
            "key": self.key,
            "secret": self.secret,
            "num_iid": item_id,
            "result_type": "json",
            "cache": "yes"
        }
        try:
            resp = requests.get(base_url, params=params, timeout=20)
            result = resp.json()
            # 判断是否请求成功
            if result.get("error_code") != "0000":
                print(f"【{datetime.now()}】商品{item_id}获取失败:{result.get('error')}")
                return None
            return result.get("item")
        except Exception as e:
            print(f"【{datetime.now()}】网络请求异常{item_id}:{str(e)}")
            return None

    def parse_sku_info(self, sku_data):
        """解析多规格SKU,格式化存储"""
        sku_res = []
        if not sku_data or "sku" not in sku_data:
            return json.dumps(sku_res, ensure_ascii=False)
        for sku in sku_data["sku"]:
            sku_res.append({
                "sku_id": sku["sku_id"],
                "spec": sku["properties_name"],
                "price": float(sku["price"]),
                "stock": int(sku["quantity"])
            })
        return json.dumps(sku_res, ensure_ascii=False)

    def check_price_alert(self, item_id, new_price):
        """对比历史价格,检测价格异动并告警"""
        df = pd.read_csv(self.data_file, encoding="utf-8-sig")
        item_history = df[df["item_id"] == item_id]
        if len(item_history) == 0:
            return
        # 获取上一次抓取的价格
        last_record = item_history.iloc[-1]
        old_price = float(last_record["current_price"])
        price_diff = abs(new_price - old_price)
        # 超出阈值触发告警
        if price_diff >= self.alert_threshold:
            if new_price < old_price:
                alert_msg = f"⚠️降价告警|商品ID:{item_id} 原价{old_price} → 现价{new_price},降幅{price_diff}元"
            else:
                alert_msg = f"⚠️涨价告警|商品ID:{item_id} 原价{old_price} → 现价{new_price},涨幅{price_diff}元"
            print(alert_msg)
            # 此处可拓展:调用企业微信/邮件接口推送消息

    def single_monitor_task(self):
        """单次监控任务:循环抓取所有商品、存储、异动检测"""
        print(f"\n===== 执行一轮监控 {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} =====")
        save_rows = []
        for item_id in self.item_ids:
            item_data = self.fetch_product_data(item_id)
            if not item_data:
                continue
            # 提取核心指标
            current_price = float(item_data.get("price", 0))
            original_price = float(item_data.get("orginal_price", 0))
            stock = int(item_data.get("num", 0))
            sales = int(item_data.get("sales", 0)) if item_data.get("sales") else 0
            shop_info = item_data.get("seller_info", {})
            shop_name = shop_info.get("shop_name", "未知店铺")
            sku_str = self.parse_sku_info(item_data.get("skus"))
            
            # 价格异动检测
            self.check_price_alert(item_id, current_price)
            
            # 组装存储行
            row = {
                "crawl_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                "item_id": item_id,
                "title": item_data.get("title", ""),
                "brand": item_data.get("brand", ""),
                "current_price": current_price,
                "original_price": original_price,
                "stock_num": stock,
                "sales": sales,
                "shop_name": shop_name,
                "sku_list": sku_str
            }
            save_rows.append(row)
            print(f"✅ 成功采集商品:{item_data.get('title')[:20]}... 现价:{current_price}")
            time.sleep(1) # 平缓请求间隔,降低压力
        # 追加写入历史数据
        if save_rows:
            pd.DataFrame(save_rows).to_csv(
                self.data_file, mode="a", header=False, index=False, encoding="utf-8-sig"
            )
        print("本轮监控完成,等待下一轮调度...")

    def start_scheduler(self):
        """启动后台定时监控任务"""
        scheduler = BackgroundScheduler()
        # 循环定时执行监控
        scheduler.add_job(
            self.single_monitor_task,
            "interval",
            minutes=self.monitor_interval,
            id="ecom_monitor_job",
            replace_existing=True
        )
        scheduler.start()
        print(f"监控系统已启动,每{self.monitor_interval}分钟自动采集一次商品数据")
        try:
            while True:
                time.sleep(60)
        except KeyboardInterrupt:
            scheduler.shutdown()
            print("监控任务已安全停止")

if __name__ == "__main__":
    monitor = EcomProductMonitor()
    # 启动自动监控
    monitor.start_scheduler()

3.2 数据分析工具脚本(data_analysis.py)

单独脚本用于读取历史时序数据,生成价格趋势、竞品对比分析报表:

import pandas as pd
import json
import matplotlib.pyplot as plt

plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False

class ProductDataAnalyzer:
    def __init__(self, data_file="product_history.csv"):
        self.df = pd.read_csv(data_file, encoding="utf-8-sig")
        self.df["crawl_time"] = pd.to_datetime(self.df["crawl_time"])

    def show_price_trend(self, target_item_id):
        """单商品价格趋势可视化"""
        item_df = self.df[self.df["item_id"] == target_item_id].sort_values("crawl_time")
        if len(item_df) == 0:
            print("无该商品历史数据")
            return
        plt.figure(figsize=(12, 6))
        plt.plot(item_df["crawl_time"], item_df["current_price"], marker="o", label="实时售价")
        plt.plot(item_df["crawl_time"], item_df["original_price"], linestyle="--", label="原价")
        plt.title(f"商品{target_item_id}价格历史趋势")
        plt.xlabel("时间")
        plt.ylabel("价格(元)")
        plt.legend()
        plt.xticks(rotation=30)
        plt.tight_layout()
        plt.show()

    def export_compete_report(self):
        """导出全竞品对比报表,计算均价、最低售价、库存均值"""
        report = []
        for item_id in self.df["item_id"].unique():
            item_df = self.df[self.df["item_id"] == item_id]
            last_record = item_df.iloc[-1]
            avg_price = round(item_df["current_price"].mean(), 2)
            min_price = item_df["current_price"].min()
            avg_stock = int(item_df["stock_num"].mean())
            total_sales = last_record["sales"]
            report.append({
                "商品ID": item_id,
                "商品标题": last_record["title"],
                "当前售价": last_record["current_price"],
                "历史均价": avg_price,
                "历史最低价": min_price,
                "平均库存": avg_stock,
                "累计销量": total_sales,
                "所属店铺": last_record["shop_name"]
            })
        report_df = pd.DataFrame(report)
        report_df.to_excel("竞品数据分析报告.xlsx", index=False)
        print("竞品对比报表已生成:竞品数据分析报告.xlsx")
        return report_df

if __name__ == "__main__":
    analyzer = ProductDataAnalyzer()
    # 1. 生成竞品对比Excel报表
    analyzer.export_compete_report()
    # 2. 查看指定商品价格走势(替换为你的商品ID)
    analyzer.show_price_trend("10335871600")

四、系统核心功能详解

4.1 全维度商品数据采集能力

运行脚本后,单次抓取即可一次性获取所有业务所需字段,无需多次请求:

  1. 基础信息:商品标题、品牌、原价、实时售价、发货地、商品详情链接;

  2. 规格 SKU 数据:全部尺寸 / 颜色规格、各规格单独价格、实时库存、子商品 ID;

  3. 店铺维度:店铺名称、自营 / 第三方标识、店铺主页;

  4. 素材信息:商品主图、详情图、规格对应素材;

  5. 运营指标:实时库存、累计销量、物流运费。

对比传统页面抓取方案,这套方案无需处理 JS 渲染、图片防盗链、分页加载等问题,返回标准化 JSON,解析成本降低 80%。

4.2 自动化定时监控与异动预警

通过 APScheduler 实现后台常驻定时任务,支持自定义监控频率(5 分钟 / 30 分钟 / 1 小时):

  • 每次抓取自动和上一轮数据对比;

  • 价格浮动超过设定阈值自动打印告警;

  • 可二次开发对接企业微信机器人、邮件、钉钉推送,实现无人值守监控。

4.3 时序化数据存储与多维度分析

所有抓取记录按时间戳存入 CSV 文件,完整留存商品全生命周期价格、库存快照,配套分析脚本实现:

  1. 单商品价格波动趋势图,直观查看大促降价、日常调价节点;

  2. 批量竞品横向对比报表,自动计算历史均价、最低价、平均库存;

  3. 导出 Excel 文件,直接用于运营周报、市场定价分析。

五、常见异常处理方案

脚本内置完整错误捕获逻辑,覆盖绝大多数线上异常场景:

  1. 商品不存在 / 下架:返回明确提示,跳过该商品继续监控其他竞品;

  2. 网络超时、请求失败:捕获异常打印日志,不中断整体监控任务;

  3. 字段空值兼容:库存、销量、店铺信息为空时自动填充默认值,避免程序崩溃;

  4. 并发限流控制:代码内置 1 秒请求间隔,平缓请求频率,保障长期稳定运行。

六、业务落地场景拓展

  1. 电商卖家竞品监控:实时盯同行调价、库存清仓活动,快速调整自身定价策略;

  2. 投放选品数据分析:长期追踪品类价格区间、爆款销量,辅助选品决策;

  3. 采购比价系统:批量监控供应商商品价格波动,降低采购成本;

  4. 市场调研自动化:定时采集品类商品数据,月度自动输出市场分析报表;

  5. 价格保护监测:监控已下单商品降价,及时申请价保。

七、部署优化建议

  1. 长期运行推荐服务器部署:Linux 服务器搭配nohup后台常驻,7×24 小时不间断监控;

  2. 数据存储升级:数据量超过万条可替换 SQLite/MySQL 数据库,提升查询速度;

  3. 告警渠道拓展:对接钉钉 / 企业微信 webhook,异动实时推送至运营群;

  4. 批量商品扩展:支持从 Excel 读取上千款商品 ID,批量加入监控队列;

  5. 缓存优化:开启内置缓存机制,重复抓取同一商品大幅提升响应速度,减少资源消耗。

总结

这套基于 OpenClaw 搭建的自动化商品监控分析系统,完美解决传统手动统计、爬虫风控两大痛点,少量代码即可实现数据采集 - 存储 - 异动预警 - 可视化分析完整闭环。

无论是个人卖家、小型电商团队,还是市场调研人员,都能快速部署落地,把每日数小时的竞品盯盘工作交给程序自动完成,释放人力聚焦运营策略、市场分析等高价值工作。


少长咸集

群贤毕至

访客