×

api 数据挖掘

5 分钟搭建京东商品自动化监控系统,低成本搞定竞品价格、库存、销量数据分析(附完整可运行 Python 源码)

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

抢沙发发表评论

前言:电商运营数据采集的普遍痛点

做京东店铺运营、选品、竞品分析的同行,几乎都会被重复性数据工作消耗大量精力:

  1. 人工定时打开竞品商品页,复制价格、库存、规格、销量到 Excel,单日至少占用 2-3 小时;

  2. 大促期间竞品调价、满减活动、库存清仓无法第一时间捕捉,错失调价应对时机;

  3. 手动记录的数据存在遗漏、录入错误,无法生成连续价格趋势、销量走势做深度分析;

  4. 原生页面采集极易触发访问限制、验证码拦截,IP 封禁风险高,批量监控完全不可行;

  5. 商用监控工具年费动辄上千,仅支持固定维度数据,无法自定义分析指标、存储历史数据。

我经过两周实操测试,基于 Open Claw 轻量化数据能力搭建了一套零复杂部署、新手友好的自动化监控方案。无需搭建分布式爬虫、不用代理 IP 池,仅需几十行 Python 代码,就能批量抓取商品全维度结构化数据,定时巡检、自动对比数据变动、持久化存储历史记录,还能拓展可视化数据分析,个人商家、中小团队都能直接落地。

一、方案整体能力介绍

1. 全维度商品数据一键结构化提取

覆盖京东商品全部运营核心字段,无需解析杂乱网页源码:

  • 基础信息:商品标题、品牌、商品 ID、商品链接、发货地、店铺名称 / 店铺 ID

  • 价格体系:日常售价、划线原价、各 SKU 规格独立定价

  • 库存规格:所有尺码 / 颜色 SKU 库存数量、规格名称、规格图片

  • 销售维度:累计销量、在售库存总量

  • 素材资源:商品主图合集、规格对应详情图

  • 物流成本:快递、EMS、基础运费

  • 店铺信息:自营 / 第三方店铺标识、店铺主页链接

2. 自动化监控核心功能

  1. 定时循环巡检:自定义监控频率(10 分钟 / 1 小时 / 每日);

  2. 增量变动识别:自动对比本次与上次采集数据,标记价格下跌、库存清零、销量暴涨;

  3. 失败重试机制:单次采集异常自动重试 3 次,单商品故障不中断整体监控流程;

  4. 缓存切换:日常监控启用缓存加速采集,价格盯盘时关闭缓存获取实时最新数据;

  5. 持久化存储:将每次采集数据存入本地文件 / 数据库,留存完整历史趋势数据。

3. 数据分析拓展空间

基于存储的历史数据,可自主实现多维度分析:

  • 价格趋势折线图:观察竞品 30 天调价周期、大促降价幅度;

  • SKU 销售占比统计:判断哪个规格是店铺主推爆款;

  • 库存波动分析:预判竞品备货周期、缺货窗口期;

  • 竞品活动复盘:记录每次满减、秒杀活动的价格区间。

二、前置准备工作

  1. 开发环境:安装 Python3.8 及以上版本,执行依赖安装命令

pip install requests schedule pandas

2.凭证获取:登录后台,获取专属身份密钥两组(后文代码key、secret 参数替换使用);

3.监控清单整理:提前收集需要监控的所有商品 ID,存入列表即可批量监控;

4.存储方案:默认使用 JSON 文件本地存储历史数据,有数据库需求可自行扩展 SQLite/MySQL。

三、完整可运行代码实现(分三大模块)

模块 1:商品数据采集封装类(基础数据拉取、异常处理)

import requests
import json
import time

class JDProductCollector:
    def __init__(self, key, secret):
        # 身份凭证,替换为自己后台获取的密钥
        self.key = key
        self.secret = secret
        self.base_url = "https://api-gw.onebound.cn/jd/item_get_pro"
        self.session = requests.Session()  # 长连接优化请求速度

    def get_product_detail(self, item_id, real_time=False):
        """
        拉取京东商品完整结构化数据
        :param item_id: 京东商品数字ID
        :param real_time: True=关闭缓存,获取实时最新价格库存;False=开启缓存提速
        :return: dict 商品结构化数据 / None 采集失败
        """
        params = {
            "key": self.key,
            "secret": self.secret,
            "api_name": "jd.item_get_pro",
            "num_iid": item_id,
            "cache": "no" if real_time else "yes",
            "result_type": "json",
            "lang": "cn"
        }
        retry_times = 3  # 采集失败自动重试3次
        for attempt in range(retry_times):
            try:
                resp = self.session.get(self.base_url, params=params, timeout=15)
                resp.raise_for_status()
                result = resp.json()
                # 判断返回状态,0000代表采集成功
                if result.get("error_code") == "0000":
                    return result["item"]
                else:
                    print(f"商品{item_id}采集异常:{result.get('reason', '未知错误')}")
                    return None
            except Exception as e:
                print(f"第{attempt+1}次采集失败,商品ID:{item_id},错误详情:{str(e)}")
                time.sleep(2)
        print(f"商品{item_id}已达到最大重试次数,采集跳过")
        return None

模块 2:监控管理类(定时巡检、数据对比、本地存储)

import schedule
import pandas as pd
from datetime import datetime
import os

class ProductMonitor:
    def __init__(self, collector, monitor_item_ids):
        self.collector = collector
        self.monitor_item_ids = monitor_item_ids  # 需要监控的商品ID列表
        self.history_file = "jd_monitor_history.json"
        self.history_data = self.load_history()  # 加载历史数据用于对比变动

    def load_history(self):
        """读取本地历史存储文件,无文件则初始化空列表"""
        if os.path.exists(self.history_file):
            with open(self.history_file, "r", encoding="utf-8") as f:
                return json.load(f)
        return []

    def save_history(self):
        """将本次采集全量数据写入本地文件持久化"""
        with open(self.history_file, "w", encoding="utf-8") as f:
            json.dump(self.history_data, f, ensure_ascii=False, indent=2)

    def compare_data_change(self, old_data, new_data):
        """对比新旧数据,识别价格、库存变动"""
        change_log = []
        old_price = float(old_data.get("price", 0))
        new_price = float(new_data.get("price", 0))
        old_stock = int(old_data.get("num", 0))
        new_stock = int(new_data.get("num", 0))

        if new_price < old_price:
            change_log.append(f"价格下跌:{old_price} → {new_price}")
        elif new_price > old_price:
            change_log.append(f"价格上调:{old_price} → {new_price}")
        if new_stock != old_stock:
            change_log.append(f"库存变动:{old_stock} → {new_stock}")
        if change_log:
            return " | ".join(change_log)
        return "无变动"

    def monitor_single_product(self, item_id):
        """单个商品采集、对比、记录逻辑"""
        now_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        product_info = self.collector.get_product_detail(item_id, real_time=True)
        if not product_info:
            return
        # 组装本次采集记录
        record = {
            "crawl_time": now_time,
            "item_id": item_id,
            "title": product_info["title"],
            "price": product_info["price"],
            "original_price": product_info["orginal_price"],
            "stock_total": product_info["num"],
            "sales": product_info.get("sales", 0),
            "shop_name": product_info.get("seller_info", {}).get("shop_name", "未知店铺"),
            "sku_list": product_info.get("skus", {}).get("sku", []),
            "raw_data": product_info
        }
        # 查询历史记录,对比变动
        item_history = [i for i in self.history_data if i["item_id"] == item_id]
        if item_history:
            latest_old = item_history[-1]
            record["change_info"] = self.compare_data_change(latest_old, record)
            if record["change_info"] != "无变动":
                print(f"【变动提醒】{record['title']} | {record['change_info']}")
        else:
            record["change_info"] = "首次采集,无历史对比"
        self.history_data.append(record)
        self.save_history()

    def full_monitor_task(self):
        """批量监控全部商品的主任务"""
        print(f"\n===== 启动一轮全量监控 {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} =====")
        for pid in self.monitor_item_ids:
            self.monitor_single_product(pid)
            time.sleep(1)  # 控制采集间隔,避免请求密集
        print("本轮监控全部完成,历史数据已保存")

    def start_timed_monitor(self, interval_hour=1):
        """启动定时循环监控,默认每小时执行一次"""
        schedule.every(interval_hour).hours.do(self.full_monitor_task)
        print(f"定时监控已启动,每{interval_hour}小时自动巡检一次商品")
        # 程序持续运行,执行定时任务
        while True:
            schedule.run_pending()
            time.sleep(60)

    def export_analysis_report(self):
        """导出Excel数据分析报表,用于趋势查看"""
        if not self.history_data:
            print("暂无监控历史数据,无法导出报表")
            return
        df = pd.DataFrame([{
            "采集时间": row["crawl_time"],
            "商品ID": row["item_id"],
            "商品标题": row["title"],
            "当前售价": row["price"],
            "原价": row["original_price"],
            "总库存": row["stock_total"],
            "总销量": row["sales"],
            "店铺名称": row["shop_name"],
            "数据变动": row["change_info"]
        } for row in self.history_data])
        save_path = f"京东商品监控报表_{datetime.now().strftime('%Y%m%d')}.xlsx"
        df.to_excel(save_path, index=False)
        print(f"数据分析报表已导出,文件路径:{save_path}")

模块 3:程序入口启动函数

if __name__ == "__main__":
    # ========== 配置区域(仅修改这里即可使用) ==========
    CLIENT_KEY = "你的后台Key"
    CLIENT_SECRET = "你的后台Secret"
    # 填入需要监控的京东商品ID列表
    MONITOR_GOODS_IDS = [
        "10335871600",
        "10057467958584"
    ]
    MONITOR_INTERVAL = 1  # 定时监控间隔,单位:小时
    # ==================================================

    # 初始化采集器与监控器
    collector = JDProductCollector(CLIENT_KEY, CLIENT_SECRET)
    monitor = ProductMonitor(collector, MONITOR_GOODS_IDS)

    # 执行一次全量采集测试
    monitor.full_monitor_task()
    # 导出当日数据分析报表
    monitor.export_analysis_report()
    # 开启定时循环监控(注释该行则只执行单次采集)
    monitor.start_timed_monitor(interval_hour=MONITOR_INTERVAL)

四、代码运行说明与效果解读

1. 基础使用步骤

  1. 将配置区域的KEYSECRET替换为个人后台凭证;

  2. MONITOR_GOODS_IDS填入需要盯盘的竞品 / 自家商品数字 ID;

  3. 运行脚本,程序会立刻执行一轮完整采集,自动生成 JSON 历史存储文件、Excel 分析报表;

  4. 开启定时监控后,程序常驻运行,每小时自动巡检,出现价格 / 库存变动会控制台打印提醒。

2. 核心数据结构说明

单次采集返回的sku_list包含每个规格独立信息:规格名称、单独售价、对应库存、规格 ID,可单独提取做 SKU 维度拆解分析; 本地 JSON 文件完整留存每一次采集的原始全量数据,后续可接入 Matplotlib/Plotly 绘制价格走势图表; 导出的 Excel 报表聚合关键指标,运营可直接发给团队做每日竞品复盘。

3. 场景化优化拓展方案

拓展 1:价格阈值钉钉 / 企业微信告警

compare_data_change函数内增加价格判断逻辑,当降价幅度超过预设阈值时,调用群机器人接口推送实时消息,无需守着控制台查看变动。

拓展 2:SQLite 数据库持久化存储

替换本地 JSON 存储逻辑,将每条监控记录写入轻量数据库,支持跨日期、跨月份大规模历史数据查询,适合长期竞品追踪。

拓展 3:多平台兼容拓展

更换对应数据通道参数,即可同步搭建淘宝、拼多多同款监控体系,实现全电商平台竞品统一监控。

拓展 4:可视化价格趋势图

基于 pandas+matplotlib 读取历史报表,自动生成单商品 30 天价格波动折线图,直观观察竞品调价节奏。

五、方案对比传统采集方案优势总结

表格

对比维度 手动 Excel 记录 原生网页爬虫 商用监控工具 Open Claw 自动化方案
部署成本 0 人力成本极高 需 IP 池、反爬适配 年费千元起 仅基础调用消耗,无额外硬件
数据完整性 字段缺失、录入错误 页面改版即失效 固定字段无法自定义 全维度结构化固定返回,不受页面改版影响
批量监控能力 无法批量 批量极易封禁 IP 商品数量有上限 无商品数量硬性限制,自定义监控清单
二次开发拓展 解析逻辑复杂难改 不支持自定义代码分析 结构化 JSON 输出,可自由对接报表、告警、BI 工具
实时性 数小时延迟 并发高时卡顿 最低 1 小时延迟 可关闭缓存秒级获取实时价格库存

六、避坑实操小贴士

  1. 日常例行监控开启cache=yes缓存模式,大幅降低消耗、提升采集速度;大促盯价、临时竞品排查切换real_time=True获取实时数据;

  2. 单次批量监控商品数量建议控制在 50 个以内,循环内增加 1 秒间隔,稳定采集不触发限流;

  3. 凭证密钥请勿明文上传公开代码仓库,生产环境建议存入环境变量加密读取;

  4. 历史存储文件定期备份,防止本地文件丢失丢失长期竞品趋势数据;

  5. 采集返回商品未找到报错时,核对商品 ID 是否正确、商品是否下架,下架商品可从监控列表移除减少无效采集。

结语

这套自动化监控体系完美解决电商从业者人工盯品、数据分析效率低下的痛点,不需要深厚爬虫、后端开发基础,复制代码修改配置即可直接落地。长期运行后积累的历史数据,能够支撑选品定价、竞品活动预判、备货周期规划等核心运营决策,中小商家完全可以替代付费第三方监控工具,大幅降低运营成本。 后续我会更新拓展教程,包含钉钉实时告警、价格趋势可视化图表、SQLite 数据库存储完整拓展代码,有实操问题可以在评论区留言交流。


少长咸集

群贤毕至

访客