1688 平台的 item_get_app 接口是获取商品原始详情数据的核心接口,专门针对移动端应用场景设计。与普通的 item_get 接口相比,它返回的数据结构更贴近 1688 APP 端展示的原始格式,包含更丰富的 B2B 场景特有字段,如批发价格、起订量、供应商信息等,对采购决策和供应链分析具有重要价值。
一、接口核心特性分析
1. 接口功能与定位
2. 认证机制
3. 核心参数与响应结构
请求参数
响应核心字段
二、Python 脚本实现
import requests
import time
import json
import logging
import re
from typing import Dict, Optional, List
from requests.exceptions import RequestException
# 配置日志
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s"
)
class Alibaba1688ItemGetAppAPI:
def __init__(self, appkey: str, appsecret: str):
"""
初始化1688商品详情API客户端
:param appkey: 1688开放平台appkey
:param appsecret: 1688开放平台appsecret
"""
self.appkey = appkey
self.appsecret = appsecret
self.base_url = "https://gw.open.1688.com/openapi"
self.access_token = None
self.token_expires_at = 0 # token过期时间戳
self.session = requests.Session()
self.session.headers.update({
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": "AlibabaApp/9.1.0 (iPhone; iOS 14.4; Scale/2.00)"
})
def _get_access_token(self) -> Optional[str]:
"""获取访问令牌"""
# 检查token是否有效
if self.access_token and self.token_expires_at > time.time() + 60:
return self.access_token
logging.info("获取新的access_token")
params = {
"method": "alibaba.oauth2.getToken",
"client_id": self.appkey,
"client_secret": self.appsecret,
"grant_type": "client_credentials",
"format": "json"
}
try:
response = self.session.get(f"{self.base_url}/gateway.do", params=params, timeout=10)
response.raise_for_status()
result = response.json()
if "error_response" in result:
logging.error(f"获取access_token失败: {result['error_response']['msg']} (错误码: {result['error_response']['code']})")
return None
self.access_token = result["access_token"]
self.token_expires_at = time.time() + result.get("expires_in", 86400) # 默认为24小时
return self.access_token
except RequestException as e:
logging.error(f"获取access_token请求异常: {str(e)}")
return None
def get_item_raw_data(self,
offer_id: str,
member_id: Optional[str] = None,
province: Optional[str] = None,
fields: Optional[str] = None) -> Optional[Dict]:
"""
获取商品原始详情数据
:param offer_id: 商品ID(1688中称为offer_id)
:param member_id: 采购商ID
:param province: 省份名称
:param fields: 需要返回的字段
:return: 商品原始数据
"""
# 获取有效的access_token
if not self._get_access_token():
return None
params = {
"method": "alibaba.item.get.app",
"client_id": self.appkey,
"access_token": self.access_token,
"offer_id": offer_id,
"format": "json",
"v": "1.0",
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S")
}
# 可选参数
if member_id:
params["member_id"] = member_id
if province:
params["province"] = province
if fields:
params["fields"] = fields
try:
response = self.session.get(f"{self.base_url}/gateway.do", params=params, timeout=20)
response.raise_for_status()
result = response.json()
if "error_response" in result:
logging.error(f"获取商品数据失败: {result['error_response']['msg']} (错误码: {result['error_response']['code']})")
return None
item_response = result.get("alibaba_item_get_app_response", {})
item_data = item_response.get("result", {})
if not item_data:
logging.warning("未获取到商品数据")
return None
# 格式化原始数据
return self._process_raw_data(item_data)
except RequestException as e:
logging.error(f"获取商品数据请求异常: {str(e)}")
return None
except json.JSONDecodeError:
logging.error(f"商品数据响应解析失败: {response.text[:200]}...")
return None
def _process_raw_data(self, raw_data: Dict) -> Dict:
"""处理原始数据,提取关键信息并格式化"""
# 基础信息提取
base_info = {
"offer_id": raw_data.get("offer_id"),
"title": raw_data.get("title"),
"sub_title": raw_data.get("sub_title"),
"detail_url": raw_data.get("detail_url"),
"category": {
"cid": raw_data.get("category_id"),
"name": raw_data.get("category_name"),
"level1_cid": raw_data.get("level1_category_id"),
"level1_name": raw_data.get("level1_category_name"),
"level2_cid": raw_data.get("level2_category_id"),
"level2_name": raw_data.get("level2_category_name")
},
"tags": raw_data.get("tags", "").split(","),
"creation_time": raw_data.get("creation_time"),
"modify_time": raw_data.get("modify_time")
}
# 价格信息提取(B2B特有的阶梯价格体系)
price_info = {
"retail_price": self._safe_float(raw_data.get("retail_price")), # 零售价
"wholesale_prices": self._format_wholesale_prices(raw_data.get("wholesale_price_list", [])), # 批发价列表
"mix_batch": { # 混批规则
"support": raw_data.get("support_mix_batch", False),
"min_amount": self._safe_float(raw_data.get("mix_batch_min_amount")),
"min_quantity": self._safe_int(raw_data.get("mix_batch_min_quantity"))
},
"currency": raw_data.get("currency", "CNY"),
"price_unit": raw_data.get("price_unit", "个")
}
# 库存与规格信息提取
sku_info = {
"total_sku": self._safe_int(raw_data.get("total_sku")),
"skus": self._format_skus(raw_data.get("skus", [])),
"specs": self._format_specs(raw_data.get("specs", [])),
"total_stock": self._safe_int(raw_data.get("total_stock")),
"sales_count": self._safe_int(raw_data.get("sales_count_30d")), # 30天销量
"unit": raw_data.get("unit", "个")
}
# 供应商信息提取(B2B核心信息)
supplier_info = {
"supplier_id": raw_data.get("supplier_id"),
"supplier_name": raw_data.get("supplier_name"),
"company_name": raw_data.get("company_name"),
"years": self._safe_int(raw_data.get("operating_years")), # 经营年限
"main_products": raw_data.get("main_products", "").split(";"),
"location": raw_data.get("location"),
"transaction": {
"turnover": self._safe_float(raw_data.get("annual_turnover")), # 年交易额
"rating": self._safe_float(raw_data.get("supplier_rating")), # 供应商评分
"repeat_rate": self._safe_float(raw_data.get("repeat_purchase_rate")), # 重复采购率
"buyer_count": self._safe_int(raw_data.get("buyer_count_30d")) # 30天买家数
},
"authentication": {
"real_name": raw_data.get("real_name_authentication", False),
"company": raw_data.get("company_authentication", False),
"gold_supplier": raw_data.get("is_gold_supplier", False), # 是否金牌供应商
"assessed_supplier": raw_data.get("is_assessed_supplier", False) # 是否实力商家
},
"contact": {
"phone": raw_data.get("contact_phone"),
"online_status": raw_data.get("online_status")
}
}
# 物流信息提取
logistics_info = {
"delivery_location": raw_data.get("delivery_location"), # 发货地
"freight_template": raw_data.get("freight_template_name"),
"delivery_time": raw_data.get("delivery_time"), # 发货时间
"transport_modes": raw_data.get("transport_modes", "").split(","), # 运输方式
"min_delivery_days": self._safe_int(raw_data.get("min_delivery_days")),
"max_delivery_days": self._safe_int(raw_data.get("max_delivery_days"))
}
# 多媒体信息提取
media_info = {
"main_images": raw_data.get("main_image_list", []),
"detail_images": raw_data.get("detail_image_list", []),
"video_url": raw_data.get("video_url"),
"video_cover": raw_data.get("video_cover")
}
# 详情描述提取
description = {
"detail": self._clean_html(raw_data.get("detail", "")),
"short_description": raw_data.get("short_description")
}
return {
"base_info": base_info,
"price_info": price_info,
"sku_info": sku_info,
"supplier_info": supplier_info,
"logistics_info": logistics_info,
"media_info": media_info,
"description": description,
"raw_data": raw_data # 保留原始数据
}
def _safe_float(self, value) -> float:
"""安全转换为float"""
try:
return float(value) if value is not None else 0.0
except (ValueError, TypeError):
return 0.0
def _safe_int(self, value) -> int:
"""安全转换为int"""
try:
return int(value) if value is not None else 0
except (ValueError, TypeError):
return 0
def _format_wholesale_prices(self, prices: List[Dict]) -> List[Dict]:
"""格式化批发价格列表(阶梯价格)"""
formatted = []
for price in prices:
formatted.append({
"min_quantity": self._safe_int(price.get("min_quantity")),
"max_quantity": self._safe_int(price.get("max_quantity")),
"price": self._safe_float(price.get("price")),
"discount": self._safe_float(price.get("discount")) # 折扣
})
# 按起订量排序
return sorted(formatted, key=lambda x: x["min_quantity"])
def _format_skus(self, skus: List[Dict]) -> List[Dict]:
"""格式化SKU列表"""
formatted = []
for sku in skus:
# 处理SKU的阶梯价格
sku_prices = []
if sku.get("price_list"):
for p in sku.get("price_list"):
sku_prices.append({
"min_quantity": self._safe_int(p.get("min_quantity")),
"price": self._safe_float(p.get("price"))
})
formatted.append({
"sku_id": sku.get("sku_id"),
"specs": sku.get("specs", []), # 规格组合
"price": self._safe_float(sku.get("price")),
"wholesale_prices": sku_prices, # SKU级别的阶梯价格
"stock": self._safe_int(sku.get("stock")),
"sales_count": self._safe_int(sku.get("sales_count")),
"image_url": sku.get("image_url")
})
return formatted
def _format_specs(self, specs: List[Dict]) -> List[Dict]:
"""格式化规格参数列表"""
formatted = []
for spec in specs:
formatted.append({
"name": spec.get("name"),
"values": [
{
"name": val.get("name"),
"image_url": val.get("image_url"),
"spec_id": val.get("spec_id")
} for val in spec.get("values", [])
]
})
return formatted
def _clean_html(self, html: str) -> str:
"""清理HTML内容,提取纯文本"""
if not html:
return ""
# 去除HTML标签
clean = re.sub(r'<.*?>', ' ', html)
# 去除多余空格和换行
clean = re.sub(r'\s+', ' ', clean).strip()
return clean
def analyze_b2b_value(self, item_data: Dict) -> Dict:
"""分析商品的B2B采购价值,生成评估报告"""
if not item_data:
return {}
# 价格优势评分(0-10分)
price_advantage = 0
if item_data["price_info"]["wholesale_prices"]:
# 基于批发价与零售价的差异计算
retail_price = item_data["price_info"]["retail_price"]
lowest_wholesale = item_data["price_info"]["wholesale_prices"][0]["price"]
if retail_price > 0 and lowest_wholesale > 0:
discount_rate = (retail_price - lowest_wholesale) / retail_price
price_advantage = min(10, round(discount_rate * 10))
# 供应商可靠性评分(0-10分)
supplier_score = 0
supplier = item_data["supplier_info"]
if supplier["authentication"]["company"]:
supplier_score += 3
if supplier["authentication"]["gold_supplier"]:
supplier_score += 2
if supplier["authentication"]["assessed_supplier"]:
supplier_score += 2
if supplier["years"] >= 3:
supplier_score += 2
if supplier["transaction"]["repeat_rate"] > 30:
supplier_score += 1
# 采购灵活性评分(0-10分)
flexibility_score = 0
if item_data["price_info"]["mix_batch"]["support"]:
flexibility_score += 5
# 基于起订量评估
min_order = item_data["price_info"]["mix_batch"]["min_quantity"] or float('inf')
if min_order <= 5:
flexibility_score += 5
elif min_order <= 20:
flexibility_score += 3
elif min_order <= 100:
flexibility_score += 1
# 物流评分(0-10分)
logistics_score = 0
logistics = item_data["logistics_info"]
if logistics["min_delivery_days"] <= 2:
logistics_score += 5
elif logistics["min_delivery_days"] <= 5:
logistics_score += 3
if len(logistics["transport_modes"]) >= 2:
logistics_score += 3
if logistics["freight_template"]:
logistics_score += 2
# 综合评分
overall_score = round((price_advantage + supplier_score + flexibility_score + logistics_score) / 4, 1)
return {
"overall_score": overall_score,
"price_advantage": {
"score": price_advantage,
"description": f"批发价最低为零售价的{round(item_data['price_info']['wholesale_prices'][0]['price']/item_data['price_info']['retail_price']*100, 1)}%" if item_data["price_info"]["retail_price"] > 0 else ""
},
"supplier_reliability": {
"score": supplier_score,
"description": f"{supplier['years']}年经营,重复采购率{supplier['transaction']['repeat_rate']}%"
},
"purchase_flexibility": {
"score": flexibility_score,
"description": f"{'支持' if item_data['price_info']['mix_batch']['support'] else '不支持'}混批,最低起订量{item_data['price_info']['mix_batch']['min_quantity'] or '未知'}"
},
"logistics_capability": {
"score": logistics_score,
"description": f"发货地{logistics['delivery_location']},{logistics['min_delivery_days']}-{logistics['max_delivery_days']}天送达"
},
"risk_assessment": {
"high_risk": overall_score < 3,
"medium_risk": 3 <= overall_score < 6,
"low_risk": overall_score >= 6
}
}
# 示例调用
if __name__ == "__main__":
# 替换为实际的appkey和appsecret(从1688开放平台获取)
APPKEY = "your_appkey"
APPSECRET = "your_appsecret"
# 替换为目标商品offer_id
OFFER_ID = "61234567890"
# 初始化API客户端
api = Alibaba1688ItemGetAppAPI(APPKEY, APPSECRET)
# 获取商品原始数据
item_data = api.get_item_raw_data(
offer_id=OFFER_ID,
# member_id="your_member_id", # 可选,采购商ID
# province="浙江省", # 可选,省份
# fields="offer_id,title,price,stock" # 可选,指定需要的字段
)
if item_data:
print(f"=== 1688商品详情 (offer_id: {OFFER_ID}) ===")
print(f"商品名称: {item_data['base_info']['title']}")
print(f"类目: {item_data['base_info']['category']['level1_name']} > {item_data['base_info']['category']['level2_name']}")
print(f"供应商: {item_data['supplier_info']['supplier_name']} ({item_data['supplier_info']['company_name']})")
print(f"经营年限: {item_data['supplier_info']['years']}年")
print(f"30天销量: {item_data['sku_info']['sales_count']}件")
print(f"30天买家数: {item_data['supplier_info']['transaction']['buyer_count']}")
print(f"重复采购率: {item_data['supplier_info']['transaction']['repeat_rate']}%")
# 价格信息
print("\n价格信息:")
print(f" 零售价: {item_data['price_info']['retail_price']}元/{item_data['price_info']['price_unit']}")
print(" 批发价:")
for i, wholesale in enumerate(item_data['price_info']['wholesale_prices'], 1):
max_qty = f"-{wholesale['max_quantity']}" if wholesale['max_quantity'] else "+"
print(f" {wholesale['min_quantity']}{max_qty}件: {wholesale['price']}元/{item_data['price_info']['price_unit']}")
# 混批信息
print("\n采购规则:")
mix_batch = item_data['price_info']['mix_batch']
print(f" 混批: {'支持' if mix_batch['support'] else '不支持'}")
if mix_batch['support']:
print(f" 最低金额: {mix_batch['min_amount']}元")
print(f" 最低数量: {mix_batch['min_quantity']}件")
# 物流信息
print("\n物流信息:")
print(f" 发货地: {item_data['logistics_info']['delivery_location']}")
print(f" 预计发货时间: {item_data['logistics_info']['delivery_time']}")
print(f" 运输方式: {', '.join(item_data['logistics_info']['transport_modes'])}")
print(f" 预计送达时间: {item_data['logistics_info']['min_delivery_days']}-{item_data['logistics_info']['max_delivery_days']}天")
# 规格信息
if item_data['sku_info']['skus']:
print("\n规格信息:")
for i, sku in enumerate(item_data['sku_info']['skus'][:3], 1):
specs = ", ".join([f"{s['name']}:{s['value']}" for s in sku['specs']]) if sku['specs'] else "标准"
print(f" {i}. {specs}: {sku['price']}元, 库存{sku['stock']}件")
# B2B价值分析
b2b_analysis = api.analyze_b2b_value(item_data)
print("\n=== B2B采购价值评估 ===")
print(f"综合评分: {b2b_analysis['overall_score']}/10分")
print(f"价格优势: {b2b_analysis['price_advantage']['score']}/10分 {b2b_analysis['price_advantage']['description']}")
print(f"供应商可靠性: {b2b_analysis['supplier_reliability']['score']}/10分 {b2b_analysis['supplier_reliability']['description']}")
print(f"采购灵活性: {b2b_analysis['purchase_flexibility']['score']}/10分 {b2b_analysis['purchase_flexibility']['description']}")
print(f"物流能力: {b2b_analysis['logistics_capability']['score']}/10分 {b2b_analysis['logistics_capability']['description']}")
print(f"风险评估: {'高风险' if b2b_analysis['risk_assessment']['high_risk'] else '中等风险' if b2b_analysis['risk_assessment']['medium_risk'] else '低风险'}")