×

DMM 商品详情 API:多品类字段异构与日文数据归一化实战方案

Ace Ace 发表于2026-09-09 17:36:08 浏览5 评论0

抢沙发发表评论

前言

DMM 联盟开放商品 ItemList 接口,是日系跨境选品、商品信息同步的数据源。网上多数示例仅做简单请求演示,忽略平台独有的业务特点:平台分为多个业务楼层(floor),不同品类返回的 JSON 字段结构差异巨大、日文文本编码、多图数组嵌套、价格存在含税 / 不含税两套字段,同时联盟接口有严格的 offset 偏移上限。本文不做入门演示,聚焦多楼层字段兼容、日文文本清洗、价格字段归一化、限流退避,封装适配定时同步任务的稳定方案。

点击获取key和secret

完整 Python 代码实现

import requests
import time

class DmmItemDetailClient:
    def __init__(self, api_id, affiliate_id):
        self.api_id = api_id
        self.affiliate_id = affiliate_id
        self.base_api = "https://api.dmm.com/affiliate/v3/ItemList"

    def fetch_detail(self, cid, floor="book", site="DMM", hits=1):
        params = {
            "api_id": self.api_id,
            "affiliate_id": self.affiliate_id,
            "site": site,
            "floor": floor,
            "cid": cid,
            "hits": hits,
            "output": "json"
        }
        try:
            resp = requests.get(self.base_api, params=params, timeout=18)
            resp.raise_for_status()
            raw_data = resp.json()
        except Exception as e:
            return {"ok":False, "msg":f"请求异常:{str(e)}", "data":None}

        result_set = raw_data.get("result", {})
        item_list = result_set.get("items", [])
        if len(item_list) == 0:
            return {"ok":False, "msg":"未匹配到商品", "data":None}
        raw_item = item_list[0]

        # 多品类异构字段归一化
        output = {
            "cid": raw_item.get("cid", ""),
            "title": raw_item.get("title", "").strip(),
            "floor": raw_item.get("floor", ""),
            "url": raw_item.get("url", ""),
            "price_with_tax": raw_item.get("price", ""),
            "price_raw": raw_item.get("price_all", ""),
            "content": raw_item.get("content", ""),
            "maker": raw_item.get("maker", {}).get("name", ""),
            "images": []
        }
        # 解析图片,兼容不同楼层图片数组结构
        image_obj = raw_item.get("image", {})
        if "list" in image_obj:
            output["images"] = [img["image_url"] for img in image_obj.get("list", [])]
        elif "large" in image_obj:
            output["images"].append(image_obj["large"])
        # 分类标签解析
        genres = raw_item.get("genre", [])
        output["genres"] = [g.get("name","") for g in genres]
        return {"ok":True, "data":output}

if __name__ == "__main__":
    client = DmmItemDetailClient(api_id="你的API_ID", affiliate_id="你的联盟ID")
    res = client.fetch_detail(cid="sample_cid", floor="book")
    print(res)

核心设计思路


  1. 多楼层异构兼容:图书、影音、游戏等不同 floor 返回字段不一样,不硬编码数组下标,采用安全的多层 get 取值,避免部分品类直接解析报错。

  2. 价格字段归一:接口同时返回标价与含税价,统一提取两个价格字段,避免业务统计时混淆税前税后金额。

  3. 图片结构兼容:部分品类图片是对象,部分为数组列表,做分支判断,统一输出图片 URL 数组。

  4. 异常分层处理:区分网络超时、商品不存在、接口返回空列表,上层任务可以做重试、跳过逻辑,不会单条失败中断批量任务。

群贤毕至

访客