前言 网上大部分
Mercari 相关示例大多直接抓取网页 HTML 解析,稳定性差,页面改版就直接失效。Mercari 公开官方 API
门槛较高,业务开发更多使用移动端开放接口,但是存在 token
时效短、响应字段混杂冗余、部分商品字段为加密占位值等问题。本文不做网页爬虫解析,聚焦移动端接口调用,增加 token
过期自动识别、无效字段过滤、售卖状态归一化处理,输出可直接用于对日选品系统的结构化数据,规避直接存储原始返回带来的脏数据问题。 前置准备 调用
Mercari 移动端商品详情接口,需要合法的请求头信息,User‑Agent、X‑Platform、X‑Device‑Id
为必填项。访问令牌 access_token 存在有效期,长时间闲置会失效,需要业务层识别 401
状态码。接口存在访问频率限制,短时间大量请求会触发访问限制。 代码核心逻辑解析 1. 会话对象复用,统一管理请求头,避免每次请求重复组装 header。 对接踩坑总结 1.access_token 绑定设备信息,Device‑Id 变更会直接导致令牌失效,两者需要配套使用。
依赖库:requests,执行pip install requests安装。
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)
2. 专门识别 401 令牌过期、403 访问受限状态,给出明确业务错误提示,方便上层做 token 刷新逻辑。
3. 售卖状态做映射归一化,原始英文状态转为业务可读标记,方便业务筛选在售商品。
4. 图片列表过滤空链接,剔除接口返回大量无关埋点字段,只保留选品业务核心字段。
2. 部分已删除商品返回空 data 节点,业务代码需要判空,不要直接读取子字段。
3. 免费包邮判断依靠shipping_payer字段,不要通过价格文本字符串判断,避免解析出错。
4. 严格控制请求间隔,高频调用极易触发风控,出现 403 封禁 IP。