×

日本 Mercari 煤炉商品详情接口:反爬与数据脱敏解析实战

Ace Ace 发表于2026-09-01 14:31:43 浏览7 评论0

抢沙发发表评论

前言

网上大部分 Mercari 相关示例大多直接抓取网页 HTML 解析,稳定性差,页面改版就直接失效。Mercari 公开官方 API 门槛较高,业务开发更多使用移动端开放接口,但是存在 token 时效短、响应字段混杂冗余、部分商品字段为加密占位值等问题。本文不做网页爬虫解析,聚焦移动端接口调用,增加 token 过期自动识别、无效字段过滤、售卖状态归一化处理,输出可直接用于对日选品系统的结构化数据,规避直接存储原始返回带来的脏数据问题。

前置准备

调用 Mercari 移动端商品详情接口,需要合法的请求头信息,User‑Agent、X‑Platform、X‑Device‑Id 为必填项。访问令牌 access_token 存在有效期,长时间闲置会失效,需要业务层识别 401 状态码。接口存在访问频率限制,短时间大量请求会触发访问限制。
依赖库:requests,执行pip install requests安装。

点击获取key和secret

import requests
import time

class MercariJpDetailClient:
    def __init__(self, access_token, device_id):
        self.access_token = access_token
        self.device_id = device_id
        self.base_url = "https://api.mercari.jp/v2/items"
        self.session = requests.Session()
        self.headers = {
            "X-Device-Id": self.device_id,
            "X-Platform": "android",
            "Authorization": f"Bearer {self.access_token}",
            "User-Agent": "Mercari/6.200.0 (Linux; Android)"
        }

    def get_item_detail(self, item_id):
        url = f"{self.base_url}/{item_id}"
        try:
            resp = self.session.get(url, headers=self.headers, timeout=12)
            # token过期识别
            if resp.status_code == 401:
                return {"success": False, "error": "access_token已过期,请更新令牌"}
            if resp.status_code == 403:
                time.sleep(4)
                resp = self.session.get(url, headers=self.headers, timeout=12)
            resp.raise_for_status()
            raw_data = resp.json()
        except requests.exceptions.RequestException as e:
            return {"success": False, "error": f"网络请求异常:{str(e)}"}

        item = raw_data.get("data", {})
        # 状态归一化:on_sale在售,sold_out已售出
        status_map = {"on_sale":"在售","sold_out":"已售出","trading":"交易中"}
        sale_status = status_map.get(item.get("status"), "未知状态")

        image_list = [img.get("thumbnail_url") for img in item.get("photos",[]) if img.get("thumbnail_url")]

        result = {
            "success": True,
            "item_id": item.get("id"),
            "title": item.get("title",""),
            "description": item.get("description",""),
            "price": int(item.get("price",0)),
            "status_text": sale_status,
            "seller_id": item.get("seller",{}).get("id",""),
            "seller_name": item.get("seller",{}).get("username",""),
            "images": image_list,
            "category_id": item.get("category",{}).get("id",""),
            "is_shipping_free": item.get("shipping_payer") == "seller"
        }
        return result

if __name__ == "__main__":
    client = MercariJpDetailClient(access_token="你的token", device_id="你的设备ID")
    output = client.get_item_detail(item_id="商品ID")
    print(output)

代码核心逻辑解析

1. 会话对象复用,统一管理请求头,避免每次请求重复组装 header。
2. 专门识别 401 令牌过期、403 访问受限状态,给出明确业务错误提示,方便上层做 token 刷新逻辑。
3. 售卖状态做映射归一化,原始英文状态转为业务可读标记,方便业务筛选在售商品。
4. 图片列表过滤空链接,剔除接口返回大量无关埋点字段,只保留选品业务核心字段。

对接踩坑总结

1.access_token 绑定设备信息,Device‑Id 变更会直接导致令牌失效,两者需要配套使用。
2. 部分已删除商品返回空 data 节点,业务代码需要判空,不要直接读取子字段。
3. 免费包邮判断依靠shipping_payer字段,不要通过价格文本字符串判断,避免解析出错。
4. 严格控制请求间隔,高频调用极易触发风控,出现 403 封禁 IP。

群贤毕至

访客