×

api 数据挖掘

Python 实战|搭建电商商品自动化监控与数据分析小工具,告别手工复制粘贴

admin admin 发表于2026-10-20 14:26:03 浏览14 评论0

抢沙发发表评论

适用场景:竞品跟踪、价格盯盘、库存监控、市场数据分析;适合商家、运营、数据分析同学直接上手跑通,代码可直接二次改造。


前言

做电商运营或者竞品调研的时候,很多人都有这样的痛点: 想要盯一批商品的价格变动、库存余量、规格变化,每次都要手动打开网页一个个复制记录。商品一多,耗时巨大,还很容易错过促销降价、库存清空的关键节点。

如果直接写网页解析,还会遇到频繁的访问限制、页面结构改版、验证码等一堆麻烦,调试就要耗费大量时间。

今天分享一套轻量的实现方案,借助 Open Claw 能力,只需要商品编号,就能拿到完整结构化商品信息;再搭配 Python 脚本,实现定时巡检、异动提醒、历史数据存储、简单统计分析,快速拥有一套属于自己的监控小工具。

环境依赖:Python3.7+,需要安装 requests、pandas、schedule。

pip install requests pandas schedule

整体实现思路

  1. 配置凭证与监控清单:填入自己的访问凭证,录入需要盯的商品编号列表。

  2. 定时拉取商品全量信息:获取标题、售价、原价、库存、多规格 SKU、店铺、图片等完整信息。

  3. 数据持久化保存:每次采集结果写入 Excel,留存历史记录,方便后续做对比分析。

  4. 异动检测逻辑:对比上一次记录,价格涨跌、库存低于阈值就在控制台输出告警提示。

  5. 简易数据分析:统计一段时间内最高价、最低价、价格波动幅度,输出简报。

完整可运行代码

# -*- coding: utf-8 -*-
import requests
import json
import time
import schedule
import pandas as pd
from datetime import datetime

# ======================【请修改这里的配置参数】======================
ACCESS_KEY = "你的访问key"
ACCESS_SECRET = "你的安全密钥"

# 需要监控的商品编号列表,可以放多个
MONITOR_GOODS = [
    "10335871600",
    "10057467958584"
]

# 预警阈值设置
PRICE_DROP_ALERT = 0.10   # 价格下跌超过10%提醒
STOCK_WARN_NUM = 50       # 库存低于50触发库存告警
CHECK_PERIOD = 60 * 60    # 巡检间隔,单位秒,这里1小时跑一次
EXPORT_FILE = "商品监控历史记录.xlsx"
# =================================================================

def fetch_goods_detail(goods_id):
    """获取单个商品结构化数据"""
    base_url = "https://api-gw.onebound.cn/jd/item_get_pro/"
    params = {
        "key": ACCESS_KEY,
        "secret": ACCESS_SECRET,
        "num_iid": goods_id,
        "cache": "no",
        "result_type": "json"
    }
    headers = {
        "Accept-Encoding": "gzip",
        "Connection": "close"
    }
    try:
        resp = requests.get(base_url, params=params, headers=headers, timeout=20)
        res_json = resp.json()
        error_code = res_json.get("error_code")
        if error_code != "0000":
            print(f"【异常】商品{goods_id}获取失败,原因:{res_json.get('reason','未知错误')}")
            return None
        item_data = res_json.get("item")
        return item_data
    except Exception as e:
        print(f"网络请求异常 goods_id:{goods_id} ,err:{str(e)}")
        return None


def parse_item(raw_item):
    """把原始返回数据,提取我们需要的核心字段"""
    if not raw_item:
        return None
    data = {
        "crawl_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        "goods_id": raw_item.get("num_iid"),
        "title": raw_item.get("title", ""),
        "brand": raw_item.get("brand", ""),
        "shop_name": raw_item.get("seller_info", {}).get("shop_name", ""),
        "current_price": float(raw_item.get("price", 0) or 0),
        "origin_price": float(raw_item.get("orginal_price",0) or 0),
        "stock": int(raw_item.get("num",0) or 0),
        "sales": int(raw_item.get("sales",0) or 0),
        "detail_url": raw_item.get("detail_url",""),
    }
    return data


def save_to_excel(data_list):
    """追加写入Excel保存历史记录"""
    new_df = pd.DataFrame(data_list)
    try:
        old_df = pd.read_excel(EXPORT_FILE)
        merge_df = pd.concat([old_df, new_df], ignore_index=True)
    except FileNotFoundError:
        merge_df = new_df
    merge_df.to_excel(EXPORT_FILE, index=False)


def check_alert(new_data, history_df):
    """异动告警判断:价格、库存"""
    goods_id = new_data["goods_id"]
    same_goods = history_df[history_df["goods_id"] == goods_id]
    if len(same_goods) <= 0:
        return []
    last_row = same_goods.iloc[-1]
    alerts = []
    # 价格下跌检测
    old_price = last_row["current_price"]
    new_price = new_data["current_price"]
    if old_price > 0 and new_price > 0:
        drop_rate = (old_price - new_price) / old_price
        if drop_rate >= PRICE_DROP_ALERT:
            alerts.append(f"⚠降价预警!商品【{new_data['title']}】 由{old_price} → {new_price},跌幅{round(drop_rate*100,2)}%")
    # 库存预警
    if new_data["stock"] <= STOCK_WARN_NUM:
        alerts.append(f"⚠库存预警!商品【{new_data['title']}】 当前库存仅剩 {new_data['stock']}")
    return alerts


def simple_analysis(goods_id):
    """简单数据分析:读取本地历史,输出最高价、最低价、均值"""
    try:
        df = pd.read_excel(EXPORT_FILE)
        target = df[df["goods_id"] == goods_id]
        if len(target) == 0:
            return None
        info = {
            "goods_id": goods_id,
            "title": target.iloc[-1]["title"],
            "max_price": round(target["current_price"].max(),2),
            "min_price": round(target["current_price"].min(),2),
            "avg_price": round(target["current_price"].mean(),2),
            "record_count": len(target)
        }
        return info
    except:
        return None


def monitor_task():
    """单次巡检主任务"""
    print("\n==========开始一轮巡检 {}==========".format(datetime.now()))
    collect_result = []
    for gid in MONITOR_GOODS:
        raw = fetch_goods_detail(gid)
        item = parse_item(raw)
        if not item:
            continue
        collect_result.append(item)
        print(f"采集成功|{item['goods_id']}|{item['title'][:25]}...|现价:{item['current_price']}|库存:{item['stock']}")

    # 保存数据
    if len(collect_result) >0:
        save_to_excel(collect_result)

    # 读取全部历史用于告警
    try:
        history_all = pd.read_excel(EXPORT_FILE)
    except:
        history_all = pd.DataFrame()

    # 输出告警信息
    for row in collect_result:
        alert_list = check_alert(row, history_all)
        for msg in alert_list:
            print(msg)

    # 输出统计简报
    print("\n----------本轮数据分析简报----------")
    for gid in MONITOR_GOODS:
        ana = simple_analysis(gid)
        if ana:
            print(f"商品:{ana['title'][:22]}  最高{ana['max_price']} 最低{ana['min_price']} 均价{ana['avg_price']} 记录数:{ana['record_count']}")
    print("==========本轮巡检结束==========\n")


if __name__ == "__main__":
    print("监控程序已启动,按 Ctrl+C 停止程序")
    monitor_task() # 先立刻执行一次
    schedule.every(CHECK_PERIOD).seconds.do(monitor_task)
    while True:
        schedule.run_pending()
        time.sleep(1)

使用步骤说明

  1. 将代码中ACCESS_KEY、ACCESS_SECRET替换为自己的凭证,修改MONITOR_GOODS填入需要监控的商品编号。

  2. 按需修改预警阈值:降价提醒比例、库存告警数量、巡检时间间隔。

  3. 直接运行脚本:python goods_monitor.py

  4. 运行之后程序会:

    • 立刻执行一次数据拉取;

    • 按照设定间隔自动循环巡检;

    • 本地生成商品监控历史记录.xlsx,保存全部历史采集数据;

    • 控制台打印日志,出现降价、库存不足时输出警告;

    • 每轮结束输出简单统计简报,看到该商品历史最高、最低、平均价格。

可以拓展的方向

  1. 消息通知:把告警信息接入企业微信、钉钉机器人,不用盯着控制台,异动直接推送消息。

  2. 多规格 SKU 深度监控:代码示例只取了商品主价格,可以进一步解析 skus 数组,对每一个子规格分别做价格、库存跟踪。

  3. 可视化图表:利用 matplotlib 或者 pyecharts 读取 Excel 历史数据,绘制价格趋势曲线图。

  4. 存储升级:数据量大之后,可以把存储从 Excel 替换成 SQLite 或者 MySQL,更适合长期大量数据。

  5. 批量商品导入:从 csv 读取一大批商品 ID,实现上百个商品批量监控。

踩坑小提示

  1. 不要把巡检间隔设置过小,过于频繁会触发访问限制,建议最少间隔 30 分钟以上。

  2. 部分商品会返回价格不准,这是平台数据特性,做监控时需要留意,不要完全依赖单一数值做决策。

  3. 遇到商品下架,脚本会打印异常日志,方便你及时清理监控列表。

  4. 服务器部署可以使用 nohup 或者 systemd 后台常驻,实现 7×24 小时不间断监控。

这套工具把我们从重复复制粘贴网页的工作中解放出来,把精力更多放在数据分析和业务决策上,而不是机械的数据收集。你可以基于这份基础代码,根据自己业务需求不断迭代改造。


少长咸集

群贤毕至

访客