Python结合京东API实现竞品分析系统

简介: 你想要用 Python 结合京东 API 搭建一套「竞品分析系统」,核心目标是批量抓取竞品商品数据、进行多维度对比分析(价格、销量、库存等)、生成可视化分析报告。我会提供完整可落地的方案,涵盖「数据采集 → 数据存储 → 多维度分析 → 可视化输出」全流程,兼顾实用性和易扩展性。

你想要用 Python 结合京东 API 搭建一套「竞品分析系统」,核心目标是批量抓取竞品商品数据、进行多维度对比分析(价格、销量、库存等)、生成可视化分析报告。我会提供完整可落地的方案,涵盖「数据采集 → 数据存储 → 多维度分析 → 可视化输出」全流程,兼顾实用性和易扩展性。

一、核心设计思路

1. 系统架构

image.png

2. 核心特性

  • 多维度分析:价格对比、销量排行、库存状态、价格波动趋势;
  • 自动化:定时批量采集数据,自动生成分析报告;
  • 可视化:用matplotlib/plotly生成直观的图表(柱状图 / 折线图);
  • 易扩展:支持新增分析维度(如好评率、店铺评分)。

3. 技术栈

  • 数据采集:requests(京东 API 调用)、threading(批量采集提速);
  • 数据存储:pandas(数据处理)、csv(轻量存储)、pymysql(可选数据库存储);
  • 可视化:matplotlib(基础图表)、plotly(交互式图表,可选);
  • 定时任务:schedule(自动更新数据)。

二、前置准备

1. 安装依赖库

bash

运行

# 核心依赖:API请求 + 数据处理 + 可视化 + 定时任务
pip install requests pandas matplotlib schedule pymysql python-dotenv

2. 基础配置

  • 京东 API 密钥:在聚合数据官网领取「京东商品详情 API」的AppKey(免费版足够测试,生产可升级);
  • 竞品配置:整理需要分析的竞品列表(按品类分组,如「保温杯」「充电宝」)。

三、完整系统代码

1. 配置文件(.env)

ini

# .env 文件(敏感配置分离)
JD_API_KEY=你的聚合数据AppKey
# 可选:MySQL配置(不用数据库则留空)
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=你的数据库密码
DB_NAME=jd_competitor_analysis

2. 核心代码(jd_competitor_analysis.py)

python

运行

import requests
import pandas as pd
import matplotlib.pyplot as plt
import schedule
import time
import os
import json
from datetime import datetime
from dotenv import load_dotenv
import threading
import pymysql
from pymysql.err import OperationalError
# 加载配置
load_dotenv()
plt.rcParams["font.sans-serif"] = ["SimHei"]  # 解决中文显示问题
plt.rcParams["axes.unicode_minus"] = False
# ===================== 全局配置 =====================
# API配置
JD_API_KEY = os.getenv("JD_API_KEY")
JD_API_URL = "https://v.juhe.cn/jd/item/detail"
# 竞品配置(核心:按品类分组,配置商品ID、名称、品牌)
COMPETITOR_CONFIG = {
    "保温杯": [
        {"sku_id": "100060195820", "name": "京东京造轻量保温杯", "brand": "京东京造"},
        {"sku_id": "100080907904", "name": "膳魔师不锈钢保温杯", "brand": "膳魔师"},
        {"sku_id": "100095380451", "name": "象印便携保温杯", "brand": "象印"}
    ],
    "充电宝": [
        {"sku_id": "100012345678", "name": "小米充电宝20000mAh", "brand": "小米"},
        {"sku_id": "100012345679", "name": "罗马仕充电宝10000mAh", "brand": "罗马仕"},
        {"sku_id": "100012345680", "name": "品胜充电宝15000mAh", "brand": "品胜"}
    ]
}
# 数据存储路径
DATA_DIR = "jd_competitor_data"
CSV_FILE = os.path.join(DATA_DIR, "competitor_data.csv")
REPORT_DIR = "jd_competitor_reports"
# 定时更新频率(单位:小时)
UPDATE_INTERVAL = 1
# ====================================================
# 初始化目录
os.makedirs(DATA_DIR, exist_ok=True)
os.makedirs(REPORT_DIR, exist_ok=True)
class JDCompetitorAnalyzer:
    def __init__(self):
        self.api_key = JD_API_KEY
        self.competitor_config = COMPETITOR_CONFIG
        self.data = pd.DataFrame()  # 存储所有竞品数据
    def get_item_detail(self, sku_id):
        """调用京东API获取单个商品详情"""
        params = {
            "key": self.api_key,
            "sku_id": sku_id
        }
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
        }
        try:
            response = requests.get(JD_API_URL, params=params, headers=headers, timeout=10)
            if response.status_code == 200:
                result = response.json()
                if result["error_code"] == 0:
                    item = result["result"]
                    # 提取核心字段(标准化)
                    return {
                        "品类": "",  # 后续填充
                        "商品ID": sku_id,
                        "商品名称": item.get("title", ""),
                        "品牌": "",  # 后续填充
                        "价格": float(item.get("price", 0.0)),
                        "销量": item.get("sales", "0"),
                        "库存状态": item.get("stock_state", "未知"),
                        "店铺名称": item.get("shop_name", ""),
                        "采集时间": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                    }
                else:
                    print(f"API调用失败({sku_id}):{result['reason']}")
            else:
                print(f"HTTP请求失败({sku_id}):状态码{response.status_code}")
        except Exception as e:
            print(f"获取商品数据异常({sku_id}):{str(e)}")
        return None
    def batch_collect_data(self):
        """批量采集所有竞品数据"""
        print(f"\n[{datetime.now()}] 开始批量采集竞品数据...")
        all_data = []
        # 多线程采集(提升效率)
        lock = threading.Lock()
        threads = []
        def collect_category(category, items):
            """采集单个品类的商品数据"""
            category_data = []
            for item in items:
                detail = self.get_item_detail(item["sku_id"])
                if detail:
                    detail["品类"] = category
                    detail["品牌"] = item["brand"]
                    category_data.append(detail)
                    print(f"✅ 采集完成:{category} - {item['name']}")
            with lock:
                all_data.extend(category_data)
        # 启动线程
        for category, items in self.competitor_config.items():
            t = threading.Thread(target=collect_category, args=(category, items))
            threads.append(t)
            t.start()
        # 等待所有线程完成
        for t in threads:
            t.join()
        # 转换为DataFrame并存储
        if all_data:
            self.data = pd.DataFrame(all_data)
            # 追加写入CSV(保留历史数据)
            if os.path.exists(CSV_FILE):
                self.data.to_csv(CSV_FILE, mode="a", header=False, index=False, encoding="utf-8-sig")
            else:
                self.data.to_csv(CSV_FILE, index=False, encoding="utf-8-sig")
            print(f"✅ 批量采集完成,共采集{len(all_data)}条数据,已保存到{CSV_FILE}")
        else:
            print("❌ 未采集到任何数据")
    def load_historical_data(self):
        """加载历史采集数据"""
        if os.path.exists(CSV_FILE):
            self.data = pd.read_csv(CSV_FILE, encoding="utf-8-sig")
            print(f"✅ 加载历史数据完成,共{len(self.data)}条")
        else:
            print("⚠️ 无历史数据,先执行批量采集")
    def analyze_price(self, category=None):
        """价格分析:对比同品类商品价格,生成柱状图"""
        self.load_historical_data()
        if self.data.empty:
            return
        # 筛选品类(默认分析所有)
        analyze_data = self.data if category is None else self.data[self.data["品类"] == category]
        if analyze_data.empty:
            print(f"❌ 无{category}品类的分析数据")
            return
        # 取最新采集的价格(按采集时间排序)
        analyze_data["采集时间"] = pd.to_datetime(analyze_data["采集时间"])
        latest_data = analyze_data.sort_values("采集时间").groupby(["品类", "商品ID"]).last().reset_index()
        # 生成价格对比图
        plt.figure(figsize=(12, 6))
        for category in latest_data["品类"].unique():
            cat_data = latest_data[latest_data["品类"] == category]
            plt.bar(
                [f"{row['品牌']}\n{row['商品名称'][:8]}..." for _, row in cat_data.iterrows()],
                cat_data["价格"],
                label=category
            )
        plt.title("京东竞品价格对比分析", fontsize=14)
        plt.xlabel("商品(品牌+名称)", fontsize=12)
        plt.ylabel("价格(元)", fontsize=12)
        plt.xticks(rotation=45, ha="right")
        plt.legend()
        plt.tight_layout()
        # 保存图表
        price_report_path = os.path.join(REPORT_DIR, f"价格对比分析_{datetime.now().strftime('%Y%m%d%H%M')}.png")
        plt.savefig(price_report_path, dpi=300)
        print(f"✅ 价格分析完成,图表已保存到{price_report_path}")
    def analyze_sales(self, category=None):
        """销量分析:同品类销量排行,生成横向柱状图"""
        self.load_historical_data()
        if self.data.empty:
            return
        analyze_data = self.data if category is None else self.data[self.data["品类"] == category]
        if analyze_data.empty:
            print(f"❌ 无{category}品类的分析数据")
            return
        # 处理销量数据(统一格式:提取数字)
        def parse_sales(sales_str):
            if pd.isna(sales_str) or sales_str == "暂无数据":
                return 0
            sales_str = str(sales_str).replace("+", "").replace("万", "0000")
            try:
                return int(float(sales_str.replace(" ", "")))
            except:
                return 0
        analyze_data["销量数值"] = analyze_data["销量"].apply(parse_sales)
        latest_data = analyze_data.sort_values("采集时间").groupby(["品类", "商品ID"]).last().reset_index()
        # 生成销量排行图
        plt.figure(figsize=(12, 6))
        for category in latest_data["品类"].unique():
            cat_data = latest_data[latest_data["品类"] == category].sort_values("销量数值", ascending=True)
            plt.barh(
                [f"{row['品牌']}\n{row['商品名称'][:8]}..." for _, row in cat_data.iterrows()],
                cat_data["销量数值"],
                label=category
            )
        plt.title("京东竞品销量排行分析", fontsize=14)
        plt.xlabel("销量(数值)", fontsize=12)
        plt.ylabel("商品(品牌+名称)", fontsize=12)
        plt.legend()
        plt.tight_layout()
        # 保存图表
        sales_report_path = os.path.join(REPORT_DIR, f"销量排行分析_{datetime.now().strftime('%Y%m%d%H%M')}.png")
        plt.savefig(sales_report_path, dpi=300)
        print(f"✅ 销量分析完成,图表已保存到{sales_report_path}")
    def generate_summary_report(self):
        """生成竞品分析汇总报告(文本+图表)"""
        print(f"\n[{datetime.now()}] 开始生成竞品分析汇总报告...")
        self.load_historical_data()
        if self.data.empty:
            return
        # 生成价格和销量分析图表
        self.analyze_price()
        self.analyze_sales()
        # 生成文本汇总报告
        summary = []
        summary.append(f"# 京东竞品分析汇总报告({datetime.now().strftime('%Y-%m-%d %H:%M:%S')})")
        summary.append(f"## 数据概况")
        summary.append(f"- 采集品类数:{len(self.data['品类'].unique())}")
        summary.append(f"- 商品总数:{len(self.data['商品ID'].unique())}")
        summary.append(f"- 历史数据总量:{len(self.data)}条")
        # 按品类汇总
        summary.append("\n## 各品类分析")
        for category in self.data["品类"].unique():
            cat_data = self.data[self.data["品类"] == category]
            latest_cat = cat_data.sort_values("采集时间").groupby("商品ID").last().reset_index()
            summary.append(f"\n### {category}")
            # 价格最低商品
            min_price_item = latest_cat.loc[latest_cat["价格"].idxmin()]
            summary.append(f"- 价格最低:{min_price_item['品牌']} {min_price_item['商品名称'][:20]}...({min_price_item['价格']}元)")
            # 销量最高商品
            latest_cat["销量数值"] = latest_cat["销量"].apply(lambda x: parse_sales(x) if pd.notna(x) else 0)
            max_sales_item = latest_cat.loc[latest_cat["销量数值"].idxmax()]
            summary.append(f"- 销量最高:{max_sales_item['品牌']} {max_sales_item['商品名称'][:20]}...({max_sales_item['销量']})")
            # 库存状态统计
            stock_stats = latest_cat["库存状态"].value_counts().to_dict()
            summary.append(f"- 库存状态:{stock_stats}")
        # 保存文本报告
        report_path = os.path.join(REPORT_DIR, f"竞品分析汇总报告_{datetime.now().strftime('%Y%m%d%H%M')}.md")
        with open(report_path, "w", encoding="utf-8") as f:
            f.write("\n".join(summary))
        print(f"✅ 汇总报告生成完成,已保存到{report_path}")
    def run_scheduled_task(self):
        """启动定时任务:自动采集+分析"""
        print(f"\n[{datetime.now()}] 启动竞品分析定时任务,每{UPDATE_INTERVAL}小时更新一次...")
        # 立即执行一次
        self.batch_collect_data()
        self.generate_summary_report()
        # 配置定时任务
        schedule.every(UPDATE_INTERVAL).hours.do(self.batch_collect_data)
        schedule.every(UPDATE_INTERVAL).hours.do(self.generate_summary_report)
        # 持续运行
        while True:
            schedule.run_pending()
            time.sleep(60)
# 辅助函数:解析销量数值
def parse_sales(sales_str):
    if pd.isna(sales_str) or sales_str == "暂无数据":
        return 0
    sales_str = str(sales_str).replace("+", "").replace("万", "0000")
    try:
        return int(float(sales_str.replace(" ", "")))
    except:
        return 0
# 主函数
if __name__ == "__main__":
    analyzer = JDCompetitorAnalyzer()
    # 可选操作:
    # 1. 单次批量采集+生成报告
    # analyzer.batch_collect_data()
    # analyzer.generate_summary_report()
    # 2. 启动定时任务(自动采集+分析)
    analyzer.run_scheduled_task()

四、代码核心说明

1. 关键功能模块

表格

方法 核心作用 亮点
get_item_detail 单商品数据采集 异常捕获 + 字段标准化,保证数据一致性
batch_collect_data 批量采集 多线程提速,按品类分组采集,追加保存历史数据
analyze_price 价格对比分析 生成柱状图,支持单品类 / 全品类分析
analyze_sales 销量排行分析 处理非标准销量数据(如「10 万 +」),生成横向柱状图
generate_summary_report 汇总报告生成 文本报告(MD 格式)+ 可视化图表,自动汇总关键指标
run_scheduled_task 定时任务 自动采集 + 分析,支持自定义更新频率

2. 核心配置修改

  • COMPETITOR_CONFIG:替换为你的竞品列表,按「品类→商品」分组,填写sku_id(京东商品 ID)、name(商品名称)、brand(品牌);
  • UPDATE_INTERVAL:修改定时更新频率(建议≥1 小时,避免 API 调用超限);
  • JD_API_KEY:在.env文件中填写聚合数据的 AppKey。

3. 避坑要点

  • API 调用限制:聚合数据免费版有调用次数限制,批量采集时控制线程数和频率;
  • 销量数据处理:京东 API 返回的销量可能是「10 万 +」「暂无数据」等非标准格式,代码中已做解析;
  • 中文显示:设置plt.rcParams解决 matplotlib 中文乱码问题;
  • 数据存储:CSV 文件用utf-8-sig编码,避免 Excel 打开乱码。

五、运行与使用

1. 单次运行(采集 + 生成报告)

注释掉定时任务,执行单次采集和报告生成:

python

运行

if __name__ == "__main__":
    analyzer = JDCompetitorAnalyzer()
    analyzer.batch_collect_data()
    analyzer.generate_summary_report()

运行命令:

bash

运行

python jd_competitor_analysis.py

2. 定时运行(自动更新)

启用定时任务,程序会持续运行,按设定频率自动采集数据并生成报告:

python

运行

if __name__ == "__main__":
    analyzer = JDCompetitorAnalyzer()
    analyzer.run_scheduled_task()

3. 输出结果示例

  • 数据文件jd_competitor_data/competitor_data.csv(保留所有历史采集数据);
  • 可视化图表jd_competitor_reports/价格对比分析_202602101530.png销量排行分析_202602101530.png
  • 汇总报告jd_competitor_reports/竞品分析汇总报告_202602101530.md(Markdown 格式,可直接打开查看)。

六、进阶优化(可选)

  1. 数据库存储:替换 CSV 为 MySQL,支持更高效的历史数据查询和分析;
  2. 价格趋势分析:基于历史数据生成价格波动折线图,分析竞品调价规律;
  3. 多维度扩展:新增「好评率」「店铺评分」「配送方式」等分析维度;
  4. 告警功能:当竞品价格低于设定阈值时,触发邮件 / 钉钉告警;
  5. 交互式可视化:用plotly替换matplotlib,生成可交互的网页版图表;
  6. 数据清洗优化:处理重复数据、缺失值,提升分析准确性。

总结

  1. 核心逻辑:通过多线程批量采集京东竞品数据,基于 pandas 做数据处理,matplotlib 生成可视化图表,最终输出结构化的分析报告;
  2. 关键配置:修改COMPETITOR_CONFIG添加竞品,配置 API 密钥,调整更新频率;
  3. 实用性:支持定时自动更新,保留历史数据,可生成价格 / 销量等多维度分析报告,满足竞品分析核心需求;
  4. 扩展性:代码模块化设计,可轻松新增分析维度、告警功能、数据库存储等。

这套系统完全适配中小商家 / 个人的竞品分析需求,代码结构清晰,无需复杂的开发经验即可上手,且能根据实际需求灵活扩展功能。

相关文章
|
14天前
|
人工智能 自然语言处理 Shell
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
本教程指导用户在开源AI助手Clawdbot中集成阿里云百炼API,涵盖安装Clawdbot、获取百炼API Key、配置环境变量与模型参数、验证调用等完整流程,支持Qwen3-max thinking (Qwen3-Max-2026-01-23)/Qwen - Plus等主流模型,助力本地化智能自动化。
27905 100
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
|
9天前
|
人工智能 安全 机器人
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI助手,支持钉钉、飞书等多平台接入。本教程手把手指导Linux下部署与钉钉机器人对接,涵盖环境配置、模型选择(如Qwen)、权限设置及调试,助你快速打造私有、安全、高权限的专属AI助理。(239字)
5300 14
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
|
8天前
|
人工智能 机器人 Linux
OpenClaw(Clawdbot、Moltbot)汉化版部署教程指南(零门槛)
OpenClaw作为2026年GitHub上增长最快的开源项目之一,一周内Stars从7800飙升至12万+,其核心优势在于打破传统聊天机器人的局限,能真正执行读写文件、运行脚本、浏览器自动化等实操任务。但原版全英文界面对中文用户存在上手门槛,汉化版通过覆盖命令行(CLI)与网页控制台(Dashboard)核心模块,解决了语言障碍,同时保持与官方版本的实时同步,确保新功能最快1小时内可用。本文将详细拆解汉化版OpenClaw的搭建流程,涵盖本地安装、Docker部署、服务器远程访问等场景,同时提供环境适配、问题排查与国内应用集成方案,助力中文用户高效搭建专属AI助手。
3821 8
|
10天前
|
人工智能 机器人 Linux
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI智能体,支持飞书等多平台对接。本教程手把手教你Linux下部署,实现数据私有、系统控制、网页浏览与代码编写,全程保姆级操作,240字内搞定专属AI助手搭建!
5066 17
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手
|
3天前
|
应用服务中间件 API 网络安全
3分钟汉化OpenClaw,使用Docker快速部署启动OpenClaw(Clawdbot)教程
2026年全新推出的OpenClaw汉化版,是基于Claude API开发的智能对话系统本土化优化版本,解决了原版英文界面的使用壁垒,实现了界面、文档、指令的全中文适配。该版本采用Docker容器化部署方案,开箱即用,支持Linux、macOS、Windows全平台运行,适配个人、企业、生产等多种使用场景,同时具备灵活的配置选项和强大的扩展能力。本文将从项目简介、部署前准备、快速部署、详细配置、问题排查、监控维护等方面,提供完整的部署与使用指南,文中包含实操代码命令,确保不同技术水平的用户都能快速落地使用。
2242 0
|
10天前
|
存储 人工智能 机器人
OpenClaw是什么?阿里云OpenClaw(原Clawdbot/Moltbot)一键部署官方教程参考
OpenClaw是什么?OpenClaw(原Clawdbot/Moltbot)是一款实用的个人AI助理,能够24小时响应指令并执行任务,如处理文件、查询信息、自动化协同等。阿里云推出的OpenClaw一键部署方案,简化了复杂配置流程,用户无需专业技术储备,即可快速在轻量应用服务器上启用该服务,打造专属AI助理。本文将详细拆解部署全流程、进阶功能配置及常见问题解决方案,确保不改变原意且无营销表述。
5480 5
|
12天前
|
人工智能 JavaScript 应用服务中间件
零门槛部署本地AI助手:Windows系统Moltbot(Clawdbot)保姆级教程
Moltbot(原Clawdbot)是一款功能全面的智能体AI助手,不仅能通过聊天互动响应需求,还具备“动手”和“跑腿”能力——“手”可读写本地文件、执行代码、操控命令行,“脚”能联网搜索、访问网页并分析内容,“大脑”则可接入Qwen、OpenAI等云端API,或利用本地GPU运行模型。本教程专为Windows系统用户打造,从环境搭建到问题排查,详细拆解全流程,即使无技术基础也能顺利部署本地AI助理。
7419 16
|
12天前
|
人工智能 JavaScript API
零门槛部署本地 AI 助手:Clawdbot/Meltbot 部署深度保姆级教程
Clawdbot(Moltbot)是一款智能体AI助手,具备“手”(读写文件、执行代码)、“脚”(联网搜索、分析网页)和“脑”(接入Qwen/OpenAI等API或本地GPU模型)。本指南详解Windows下从Node.js环境搭建、一键安装到Token配置的全流程,助你快速部署本地AI助理。(239字)
5039 22