从京东商品详情 API 到结构化数据:关键字段提取与清洗策略

37 阅读9分钟

在大数据时代,电商平台如京东、淘宝上的商品数据是极具价值的信息源。这些数据可用于市场分析、竞品调研、价格监控、用户行为分析等多个领域。要利用这些数据,首先需要从电商平台提供的 API 中获取原始数据,然后进行提取、清洗和结构化处理,最终转化为可用的格式。本文将以京东商品详情 API 为例,详细介绍关键字段的提取与清洗策略,并提供相应的代码示例。

一、京东商品详情 API 概述

京东提供了丰富的 API 接口,用于获取商品信息、订单数据、用户信息等。其中,商品详情 API(例如 jd.item.get)是获取单个商品详细信息的主要接口。通过该接口,我们可以获取到商品的标题、价格、品牌、规格参数、图片链接、销售数据等大量信息。

注意:使用京东 API 需要先注册成为京东平台的开发者,获取 ApiKey 和 ApiSecret,并按照平台规定的调用规则进行操作,避免触发限流或封号等问题。

二、关键字段提取

从 API 返回的原始数据中,我们需要根据业务需求提取出关键的字段。以下是一些常见的关键字段及其说明:

字段名说明
skuId商品 SKU 编号,唯一标识一个商品
name商品名称
price商品价格
marketPrice商品市场价
brandName商品品牌名称
categoryId商品所属分类 ID
categoryName商品所属分类名称
mainImage商品主图链接
imageList商品图片列表
detail商品详情描述(HTML 格式)
parameterList商品规格参数列表
salesCount商品销量
commentCount商品评论数
shopName商品所属店铺名称
shopId商品所属店铺 ID

提取策略

  1. 明确业务需求:根据具体的应用场景,确定需要提取哪些字段。例如,进行价格监控时,重点关注 skuIdnamepricebrandName 等字段;进行竞品分析时,可能还需要提取 parameterListsalesCountcommentCount 等字段。
  2. 解析 API 返回结果:京东 API 返回的数据通常是 JSON 格式,需要对 JSON 数据进行解析,提取出所需的字段。可以使用 Python 中的 json 库或其他 JSON 解析工具来实现。
  3. 处理嵌套数据:API 返回的 JSON 数据可能存在多层嵌套结构,需要逐层遍历和提取。例如,商品的规格参数 parameterList 可能是一个列表,每个元素又是一个包含 name 和 value 的字典。

三、数据清洗策略

从 API 获取的原始数据可能存在不规范、不完整、重复等问题,需要进行清洗处理,以提高数据的质量和可用性。以下是一些常见的数据清洗策略:

  1. 处理缺失值

    • 删除法:如果某个字段的缺失值比例较高,且对业务影响不大,可以考虑直接删除该字段。
    • 填充法:如果某个字段的缺失值比例较低,可以使用合适的方法进行填充。例如,对于数值型字段,可以使用均值、中位数、众数等进行填充;对于文本型字段,可以使用默认值或最频繁出现的值进行填充。
    • 插值法:对于时间序列数据或连续型数据,可以使用插值法(如线性插值、多项式插值等)来填充缺失值。
  2. 处理重复值

    • 删除重复记录:如果数据中存在完全相同的记录,可以直接删除重复的记录。
    • 合并重复字段:如果某个字段存在重复的值,可以根据业务需求进行合并或去重。
  3. 处理异常值

    • 识别异常值:可以使用统计方法(如标准差、四分位数等)或可视化方法(如箱线图、散点图等)来识别异常值。
    • 处理异常值:对于识别出的异常值,可以根据业务需求进行处理。例如,删除异常值、修正异常值、将异常值视为缺失值进行填充等。
  4. 数据类型转换

    • 将字段转换为合适的数据类型。例如,将价格字段从字符串类型转换为数值类型,将日期字段从字符串类型转换为日期类型等。
  5. 文本清洗

    • 去除 HTML 标签:对于商品详情描述等包含 HTML 标签的文本字段,需要去除 HTML 标签,提取纯文本内容。
    • 去除特殊字符:去除文本中的特殊字符、表情符号、多余的空格等。
    • 标准化文本:将文本转换为统一的格式(如小写、大写),进行分词、词性标注等处理。
  6. 数据格式标准化

    • 对日期、时间、价格等字段进行格式标准化处理,以便于后续的分析和使用。例如,将价格字段统一保留两位小数,将日期字段统一格式化为 YYYY-MM-DD 格式等。

四、代码示例

以下是使用 Python 从京东商品详情 API 获取数据、提取关键字段并进行清洗的代码示例。

前提条件

  • 获取 ApiKey 和 ApiSecret
  • 安装必要的 Python 库:requestsjsonreBeautifulSoup 等。
import requests
import json
import re
from bs4 import BeautifulSoup
import pandas as pd
from datetime import datetime

class JDProductAPI:
    def __init__(self, app_key, app_secret):
        self.app_key = app_key
        self.app_secret = app_secret
        self.base_url = "https://api.jd.com/routerjson"
    
    def get_sign(self, params):
        # 生成签名(京东 API 要求的签名算法)
        # 此处省略签名生成的具体实现,实际使用时需要根据京东开放平台的文档进行实现
        # 签名算法通常涉及对参数进行排序、拼接、加密等操作
        return "generated_sign"
    
    def get_product_detail(self, sku_id):
        # 获取商品详情
        params = {
            "app_key": self.app_key,
            "method": "jingdong.item.jingdong.get",
            "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "format": "json",
            "v": "1.0",
            "skuId": sku_id
        }
        # 生成签名
        params["sign"] = self.get_sign(params)
        # 发送请求
        response = requests.get(self.base_url, params=params)
        if response.status_code == 200:
            return response.json()
        else:
            print(f"请求失败,状态码:{response.status_code}")
            return None

class DataProcessor:
    def extract_key_fields(self, product_data):
        # 提取关键字段
        if not product_data or "jingdong_item_jingdong_get_response" not in product_data:
            return None
        
        result = product_data["jingdong_item_jingdong_get_response"]
        if "result" not in result:
            return None
        
        product_info = result["result"]
        key_fields = {
            "skuId": product_info.get("skuId", ""),
            "name": product_info.get("name", ""),
            "price": product_info.get("price", 0),
            "marketPrice": product_info.get("marketPrice", 0),
            "brandName": product_info.get("brandName", ""),
            "categoryId": product_info.get("categoryId", ""),
            "categoryName": product_info.get("categoryName", ""),
            "mainImage": product_info.get("mainImage", ""),
            "imageList": product_info.get("imageList", []),
            "detail": product_info.get("detail", ""),
            "parameterList": product_info.get("parameterList", []),
            "salesCount": product_info.get("salesCount", 0),
            "commentCount": product_info.get("commentCount", 0),
            "shopName": product_info.get("shopName", ""),
            "shopId": product_info.get("shopId", "")
        }
        return key_fields
    
    def clean_data(self, data):
        # 清洗数据
        if not data:
            return None
        
        # 处理缺失值
        # 对于价格字段,如果缺失,填充为 0
        data["price"] = data["price"] if data["price"] is not None else 0
        data["marketPrice"] = data["marketPrice"] if data["marketPrice"] is not None else 0
        
        # 对于销量和评论数字段,如果缺失,填充为 0
        data["salesCount"] = data["salesCount"] if data["salesCount"] is not None else 0
        data["commentCount"] = data["commentCount"] if data["commentCount"] is not None else 0
        
        # 处理文本字段
        # 去除商品名称中的特殊字符
        data["name"] = re.sub(r"[^\u4e00-\u9fa5a-zA-Z0-9]", "", data["name"])
        
        # 去除商品详情中的 HTML 标签
        if data["detail"]:
            soup = BeautifulSoup(data["detail"], "html.parser")
            data["detail"] = soup.get_text().strip()
        
        # 处理规格参数列表
        if data["parameterList"]:
            cleaned_params = []
            for param in data["parameterList"]:
                param_name = param.get("name", "").strip()
                param_value = param.get("value", "").strip()
                if param_name and param_value:
                    cleaned_params.append({"name": param_name, "value": param_value})
            data["parameterList"] = cleaned_params
        
        # 数据类型转换
        # 将价格字段转换为浮点数
        data["price"] = float(data["price"]) if data["price"] != "" else 0.0
        data["marketPrice"] = float(data["marketPrice"]) if data["marketPrice"] != "" else 0.0
        
        # 将销量和评论数字段转换为整数
        data["salesCount"] = int(data["salesCount"]) if data["salesCount"] != "" else 0
        data["commentCount"] = int(data["commentCount"]) if data["commentCount"] != "" else 0
        
        # 将分类 ID 和店铺 ID 转换为字符串
        data["categoryId"] = str(data["categoryId"]) if data["categoryId"] != "" else ""
        data["shopId"] = str(data["shopId"]) if data["shopId"] != "" else ""
        
        return data

# 示例用法
if __name__ == "__main__":
    # 替换为自己的 AppKey 和 AppSecret
    app_key = "your_app_key"
    app_secret = "your_app_secret"
    
    # 初始化 API 客户端和数据处理器
    jd_api = JDProductAPI(app_key, app_secret)
    processor = DataProcessor()
    
    # 要查询的商品 SKU ID
    sku_id = "100000000000"
    
    # 获取商品详情
    product_data = jd_api.get_product_detail(sku_id)
    
    if product_data:
        # 提取关键字段
        key_fields = processor.extract_key_fields(product_data)
        
        if key_fields:
            # 清洗数据
            cleaned_data = processor.clean_data(key_fields)
            
            # 打印清洗后的数据
            print(json.dumps(cleaned_data, ensure_ascii=False, indent=2))
            
            # 可以将清洗后的数据保存到数据库或文件中
            # 例如,保存到 CSV 文件
            df = pd.DataFrame([cleaned_data])
            df.to_csv("jd_product_detail.csv", index=False, encoding="utf-8-sig")
            print("数据已保存到 jd_product_detail.csv 文件中")
        else:
            print("提取关键字段失败")
    else:
        print("获取商品详情失败")

代码说明

  1. JDProductAPI 类:封装了京东商品详情 API 的调用逻辑,包括生成签名、发送请求等。
  2. DataProcessor 类:封装了数据提取和清洗的逻辑。extract_key_fields 方法用于从 API 返回的原始数据中提取关键字段,clean_data 方法用于对提取的数据进行清洗处理。
  3. 示例用法:通过实例化 JDProductAPI 和 DataProcessor 类,调用 get_product_detail 方法获取商品详情,然后提取关键字段并进行清洗,最后将清洗后的数据保存到 CSV 文件中。

五、注意事项

  1. API 调用限制:京东开放平台对 API 的调用频率和调用次数有一定的限制,需要注意控制调用频率,避免超过限制。
  2. 数据缓存:为了减少 API 调用次数和提高数据获取效率,可以对获取到的商品数据进行缓存处理。例如,将数据保存到本地数据库或文件中,下次需要时直接从缓存中获取。
  3. 数据合法性:在使用获取到的商品数据时,需要遵守京东开放平台的相关规定和法律法规,不得用于非法用途。
  4. 异常处理:在 API 调用和数据处理过程中,可能会出现各种异常情况(如网络错误、数据格式错误等),需要进行适当的异常处理,确保程序的稳定性和可靠性。

六、总结

从京东商品详情 API 到结构化数据的过程包括 API 调用、关键字段提取和数据清洗等多个环节。通过合理的提取策略和清洗策略,可以将原始的 API 数据转化为高质量的结构化数据,为后续的数据分析和应用提供有力支持。在实际应用中,需要根据具体的业务需求和数据特点,灵活调整提取和清洗策略,以达到最佳的效果。同时,还需要注意遵守 API 调用规则和相关法律法规,确保数据的合法性和安全性。