×

api 数据挖掘

告别复杂页面解析,OpenClaw 快速搭建电商商品监控与数据分析脚本

admin admin 发表于2026-10-09 11:48:12 浏览7 评论0

抢沙发发表评论

适用场景:个人比价、商家竞品跟踪、价格库存异动监测,无需处理页面渲染、验证码等棘手问题,Python 完整实战教程。


前言

做电商相关开发或者个人薅羊毛的时候,经常有这样的需求:持续跟踪一批商品的价格变动、库存状态、规格参数变化,做历史数据分析、降价提醒、竞品对比。

如果自己手写页面解析,会遇到一堆麻烦:网页结构经常改版、动态渲染、频繁弹出人机校验,IP 访问频率高还容易被限制。调试解析规则就要耗费大量时间,经常今天写好的脚本,过几天页面一改直接全部失效。

最近体验了 OpenClaw 这套工具,它把商品页面的各类信息做了标准化输出,我们只需要传入商品编号,就能拿到结构化的标题、售价、原价、SKU 规格、库存、店铺信息、图片等全部内容,把精力放在业务逻辑:监控、存储、分析,不用再折腾页面解析。

本文就完整演示如何基于 OpenClaw,实现定时商品监控、数据本地存储、简单异动分析,完整代码可以直接复制运行。

整体思路

  1. 准备好工具的身份凭证(密钥信息),拿到需要监控的商品 ID;

  2. 编写获取商品结构化信息的基础函数;

  3. 增加异常捕获,处理商品下架、网络波动等各类异常情况;

  4. 将每次采集到的数据存入本地文件,留存历史记录;

  5. 增加定时循环,实现持续监控;

  6. 简单数据分析:对比前后两次数据,识别降价、库存变动。

提示:运行脚本前,请先安装依赖库

pip install requests pandas schedule

完整 Python 实战代码

# -*- coding:utf-8 -*-
"""
OpenClaw 电商商品监控&数据分析脚本
功能:商品信息获取、异常容错、本地保存历史、价格库存异动检测
"""
import requests
import time
import pandas as pd
import schedule
import json
from datetime import datetime

# ======================== 配置区域,请自行修改 ========================
# 你的个人凭证信息
ACCESS_KEY = "替换成你的key"
ACCESS_SECRET = "替换成你的secret"

# 需要监控的商品编号列表,可以添加多个商品ID
MONITOR_GOODS_ID = [
    "10335871600",
    "10057467958584"
]

# 监控间隔,单位秒,不要设置过小,避免调用过于频繁
MONITOR_INTERVAL = 60 * 10

# 历史数据保存文件
SAVE_FILE = "goods_monitor_history.csv"
# ====================================================================


def get_goods_detail(goods_id: str):
    """
    获取单个商品结构化数据
    goods_id:商品编号
    return: 成功返回字典,失败返回None
    """
    base_url = "https://api-gw.onebound.cn/jd/item_get_pro/"
    params = {
        "key": ACCESS_KEY,
        "secret": ACCESS_SECRET,
        "num_iid": goods_id,
        "cache": "no",   # no获取最新数据,yes读取缓存加快速度
        "result_type": "json"
    }
    headers = {
        "Accept-Encoding": "gzip",
        "Connection": "close"
    }
    try:
        resp = requests.get(base_url, params=params, headers=headers, timeout=20)
        resp_json = resp.json()
        error_code = resp_json.get("error_code")

        # 0000代表正常拿到数据
        if error_code == "0000":
            item_data = resp_json.get("item")
            return item_data
        else:
            err_msg = resp_json.get("error", "未知错误")
            print(f"【商品{goods_id}】获取失败,错误信息:{err_msg}")
            return None

    except Exception as e:
        print(f"【商品{goods_id}】网络或解析异常:{str(e)}")
        return None


def parse_item(raw_item: dict):
    """把原始返回数据,提取我们关心的核心字段"""
    if not raw_item:
        return None
    out = {}
    out["crawl_time"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    out["goods_id"] = raw_item.get("num_iid")
    out["title"] = raw_item.get("title", "")
    out["price"] = float(raw_item.get("price", 0)) if raw_item.get("price") else 0
    out["original_price"] = float(raw_item.get("orginal_price", 0)) if raw_item.get("orginal_price") else 0
    out["stock"] = raw_item.get("num", 0)
    out["shop_name"] = raw_item.get("seller_info", {}).get("shop_name", "")
    out["detail_url"] = raw_item.get("detail_url", "")
    # sku规格简单提取
    sku_list = raw_item.get("skus", {}).get("sku", [])
    sku_info = []
    for sku in sku_list:
        sku_info.append({
            "sku_id": sku.get("sku_id"),
            "spec_name": sku.get("properties_name"),
            "sku_price": sku.get("price"),
            "sku_stock": sku.get("quantity")
        })
    out["sku_info"] = json.dumps(sku_info, ensure_ascii=False)
    return out


def save_to_csv(data_row: dict):
    """单条记录追加保存到csv历史文件"""
    df_new = pd.DataFrame([data_row])
    try:
        # 文件存在就追加,不存在新建
        with open(SAVE_FILE, "r", encoding="utf-8-sig") as f:
            df_new.to_csv(SAVE_FILE, mode="a", header=False, index=False, encoding="utf-8-sig")
    except FileNotFoundError:
        df_new.to_csv(SAVE_FILE, mode="w", header=True, index=False, encoding="utf-8-sig")


last_status = {}  # 保存上一轮采集状态,用于异动对比


def monitor_task():
    """一轮完整监控任务,循环所有商品"""
    print(f"\n==========开始一轮监控 {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} ==========")
    global last_status
    for gid in MONITOR_GOODS_ID:
        item_raw = get_goods_detail(gid)
        parsed = parse_item(item_raw)
        if not parsed:
            continue
        save_to_csv(parsed)
        print(f"商品【{parsed['title'][0:25]}...】现价:{parsed['price']} 库存:{parsed['stock']}")

        # 和上一次数据对比,检测异动
        prev = last_status.get(gid)
        if prev:
            # 价格下跌
            if parsed["price"] < prev["price"]:
                print(f"⚠️ 价格异动提醒!商品{gid}发生降价,上次{prev['price']},当前{parsed['price']}")
            # 库存变动
            if parsed["stock"] != prev["stock"]:
                print(f"⚠️ 库存变动提醒!商品{gid}库存由{prev['stock']}变更为{parsed['stock']}")
        # 更新记录
        last_status[gid] = parsed
        time.sleep(2)


def analysis_history():
    """简单数据分析示例,读取本地历史,打印每个商品价格区间"""
    try:
        df = pd.read_csv(SAVE_FILE, encoding="utf-8-sig")
        print("\n----------历史数据分析结果----------")
        for goods_id in df["goods_id"].unique():
            sub = df[df["goods_id"] == goods_id]
            title = sub.iloc[0]["title"]
            min_p = sub["price"].min()
            max_p = sub["price"].max()
            print(f"商品:{title[:30]}... 历史最低:{min_p} 历史最高:{max_p},共采集{len(sub)}条记录")
    except Exception as e:
        print("暂无历史数据,等待采集完成", e)


if __name__ == "__main__":
    # 执行一次
    monitor_task()
    analysis_history()

    # 设置定时循环执行
    schedule.every(MONITOR_INTERVAL).seconds.do(monitor_task)
    print(f"\n已启动定时监控,每 {MONITOR_INTERVAL/60}分钟执行一次,Ctrl+C终止程序")
    while True:
        schedule.run_pending()
        time.sleep(1)

代码讲解

  1. get_goods_detail:核心获取函数,传入商品编号,工具会返回完整的商品全部维度信息,我们不需要处理网页;同时做了网络超时、异常返回的捕获,防止程序直接崩溃。

cache 参数:设置no获取实时最新价格库存;设置yes会读取缓存,响应更快,适合非实时分析场景。

  1. parse_item:原始返回字段比较多,这个函数做字段精简,挑选我们监控业务需要的:采集时间、商品标题、价格、原价、库存、店铺、SKU 规格,SKU 数组转字符串方便存入表格。

  2. save_to_csv:每一轮采集结果都写入本地 CSV,相当于自建一份商品时间线数据库,后续可以用 Excel、Pandas 做趋势分析。

  3. monitor_task:一轮监控主逻辑,遍历全部待监控商品;并且用last_status保存上一轮状态,对比发现降价、库存变化,控制台输出告警提示。

  4. analysis_history:读取本地保存的历史记录,统计每个商品历史最高价、最低价,简单数据分析。

  5. 主程序部分:运行一次,然后开启定时任务,按设定周期自动轮询。

常见问题踩坑说明

  1. 数据拿不到?

    • 确认密钥信息复制正确,不要有多余空格换行;

    • 确认商品编号是正确有效,下架的商品会返回对应错误提示;

    • 不要把监控间隔设置得太短,短时间大量请求会触发限制。

  2. 价格和页面显示不一致 部分大促优惠券、满减活动属于页面动态计算,拿到的是商品基础标价。多规格商品,不同规格各自有独立价格,需要看返回 SKU 列表。

  3. 数据存储 示例中用 CSV 文件存储,适合小批量监控;如果要监控几百上千个商品,可以改成 SQLite / MySQL 数据库存储。

  4. 告警扩展 当前示例只在控制台打印提醒,实际项目中可以拓展:邮件推送、企业微信、钉钉消息,实现真正的消息通知。

拓展玩法

拿到标准化结构化数据之后,可以衍生很多有意思的小项目:

  1. 个人比价助手:监控心仪家电、数码产品,降到心理价位就收到提醒;

  2. 商家竞品分析:批量跟踪同行多款竞品,记录调价节奏、库存变化;

  3. 数据报表输出:定时把历史数据生成 Excel 报表,做周度、月度价格统计;

  4. 筛选过滤 SKU:针对特定规格做监控,比如只盯某一个型号的价格变动。

写在最后

很多时候我们写脚本,大量时间消耗在网页页面适配、反爬对抗上。OpenClaw 这类工具,把网页解析这一层封装完成,直接输出干净的结构化数据。我们可以把重心放回业务逻辑:监控逻辑、数据存储、数据分析。


少长咸集

群贤毕至

访客