1688 item_review 接口深度分析及 Python 实现

1688 平台的 item_review 接口是获取商品采购商评价数据的核心接口,专注于 B2B 场景下的交易评价信息。与面向消费者的电商平台不同,1688 的评论更侧重于产品质量、供应商服务、物流速度等批发采购相关维度,对供应商评估和采购决策具有重要参考价值。

一、接口核心特性分析

  1. 接口功能与定位
  • 核心功能:获取 1688 商品的采购商评价数据,包括评价内容、评分、采购量、合作次数等 B2B 场景特有的信息

  • 数据维度

    • 基础评价:评价 ID、商品 ID、采购商信息、评价时间、评价内容
    • 评分数据:产品质量、卖家服务、物流速度等维度评分
    • 交易信息:采购数量、采购金额、合作次数、是否回头客
    • 多媒体内容:产品实拍图、质检图片
    • 追评信息:追加评价内容、长期使用反馈
  • 应用场景

    • 供应商信用评估系统
    • 采购决策辅助工具
    • 供应链风险控制
    • 同类供应商对比分析
    • 产品质量监控
  1. 认证机制

1688 开放平台采用 appkey + access_token 的认证方式:

  • 开发者在 1688 开放平台注册应用,获取 appkeyappsecret
  • 通过 appkeyappsecret 获取 access_token(通常有效期为 24 小时)
  • 每次接口调用需携带有效 access_token
  • 评论接口需要申请特定权限,部分高级数据需通过企业认证
  1. 核心参数与响应结构

请求参数

参数名 类型 是否必填 说明
offer_id String 商品 ID(1688 中称为 offer_id)
access_token String 访问令牌
page Integer 页码,默认 1
page_size Integer 每页条数,默认 20,最大 50
sort String 排序方式:newest(最新)、helpful(最有帮助)、high_rating(高分)
is_retail Boolean 是否只看零售单评价,默认 false
has_image Boolean 是否只看有图评价,默认 false

响应核心字段

  • 分页信息:总评论数、总页数、当前页码

  • 评价列表:每条评价包含

    • 评价基本信息:评价 ID、采购商信息、评价时间
    • 评分信息:产品质量、卖家服务、物流速度等评分
    • 交易信息:采购数量、金额、是否回头客
    • 评价内容:文本内容、标签
    • 多媒体:实拍图片 URL 列表
    • 追评:内容与时间

二、Python 脚本实现

以下是调用 1688 item_review 接口的完整 Python 实现,包含令牌获取、接口调用、数据解析及 B2B 场景特有的评价分析功能: import requests import time import json import logging import re from typing import Dict, Optional, List from requests.exceptions import RequestException from snownlp import SnowNLP # 用于情感分析,需安装:pip install snownlp

配置日志

logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" )

class Alibaba1688ItemReviewAPI: 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 = "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": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36" })

python 复制代码
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_reviews(self, 
                    offer_id: str, 
                    page: int = 1, 
                    page_size: int = 20,
                    sort: str = "newest",
                    is_retail: bool = False,
                    has_image: bool = False) -> Optional[Dict]:
    """
    获取商品评论
    :param offer_id: 商品ID(1688中称为offer_id)
    :param page: 页码
    :param page_size: 每页条数
    :param sort: 排序方式
    :param is_retail: 是否只看零售单评价
    :param has_image: 是否只看有图评价
    :return: 评论数据
    """
    # 验证参数
    valid_sorts = ["newest", "helpful", "high_rating"]
    if sort not in valid_sorts:
        logging.error(f"无效的排序方式: {sort},支持: {valid_sorts}")
        return None
        
    if page_size < 1 or page_size > 50:
        logging.error(f"每页条数必须在1-50之间,当前为: {page_size}")
        return None
        
    # 获取有效的access_token
    if not self._get_access_token():
        return None
        
    params = {
        "method": "alibaba.item.review.get",
        "client_id": self.appkey,
        "access_token": self.access_token,
        "offer_id": offer_id,
        "page": page,
        "page_size": page_size,
        "sort": sort,
        "is_retail": "true" if is_retail else "false",
        "has_image": "true" if has_image else "false",
        "format": "json",
        "v": "1.0",
        "timestamp": time.strftime("%Y-%m-%d %H:%M:%S")
    }
    
    try:
        response = self.session.get(f"{self.base_url}/gateway.do", params=params, timeout=15)
        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
            
        review_response = result.get("alibaba_item_review_get_response", {})
        reviews_data = review_response.get("result", {})
        
        if not reviews_data:
            logging.warning("未获取到评论数据")
            return None
            
        # 格式化评论数据
        return self._format_review_data(reviews_data)
        
    except RequestException as e:
        logging.error(f"获取评论请求异常: {str(e)}")
        return None
    except json.JSONDecodeError:
        logging.error(f"评论响应解析失败: {response.text[:200]}...")
        return None

def _format_review_data(self, review_data: Dict) -> Dict:
    """格式化评论数据"""
    # 分页信息
    pagination = {
        "total_reviews": int(review_data.get("total_count", 0)),
        "total_pages": (int(review_data.get("total_count", 0)) + int(review_data.get("page_size", 20)) - 1) // int(review_data.get("page_size", 20)),
        "current_page": int(review_data.get("current_page", 1)),
        "page_size": int(review_data.get("page_size", 20))
    }
    
    # 格式化评论列表
    reviews = []
    for review in review_data.get("reviews", []):
        # 处理评价内容(去除HTML标签)
        content = self._clean_text(review.get("content", ""))
        
        # 情感分析(0-1之间,越接近1越积极)
        sentiment_score = self._analyze_sentiment(content)
        sentiment = "positive" if sentiment_score > 0.6 else "negative" if sentiment_score < 0.4 else "neutral"
        
        # 处理评价图片
        images = []
        if review.get("images"):
            images = [img.get("url") for img in review.get("images") if img.get("url")]
        
        # 处理追评(1688中可能包含长期使用反馈)
        append_comment = None
        if review.get("append_comment"):
            append_comment = {
                "content": self._clean_text(review["append_comment"].get("content", "")),
                "created": review["append_comment"].get("gmt_create"),
                "days_after_purchase": review["append_comment"].get("days_after_purchase")  # 购买后多少天追评
            }
        
        # 处理交易信息(B2B特有的采购信息)
        trade_info = {
            "purchase_quantity": int(review.get("purchase_quantity", 0)),  # 采购数量
            "purchase_amount": float(review.get("purchase_amount", 0)),  # 采购金额
            "is_repeat_buyer": review.get("is_repeat_buyer", False),  # 是否回头客
            "cooperation_count": int(review.get("cooperation_count", 1)),  # 合作次数
            "purchase_time": review.get("purchase_time")  # 采购时间
        }
        
        reviews.append({
            "review_id": review.get("review_id"),
            "buyer": {
                "user_id": review.get("buyer_user_id"),
                "nickname": review.get("buyer_nick"),
                "level": review.get("buyer_level"),  # 采购商等级
                "region": review.get("buyer_region")  # 采购商地区
            },
            "rating": {
                "product_quality": int(review.get("product_quality_rating", 0)),  # 产品质量评分
                "seller_service": int(review.get("seller_service_rating", 0)),  # 卖家服务评分
                "logistics_speed": int(review.get("logistics_speed_rating", 0)),  # 物流速度评分
                "match_description": int(review.get("match_description_rating", 0))  # 与描述相符度
            },
            "content": content,
            "created_time": review.get("gmt_create"),
            "images": images,
            "append_comment": append_comment,
            "useful_count": int(review.get("useful_count", 0)),  # 有用数
            "tags": review.get("tags", "").split(","),  # 评价标签
            "trade_info": trade_info,
            "is_retail": review.get("is_retail", False),  # 是否零售单
            "sentiment": {
                "score": round(sentiment_score, 4),
                "label": sentiment
            }
        })
    
    return {
        "pagination": pagination,
        "reviews": reviews,
        "raw_data": review_data  # 保留原始数据
    }

def _clean_text(self, text: str) -> str:
    """清理文本,去除HTML标签和特殊字符"""
    if not text:
        return ""
    # 去除HTML标签
    clean = re.sub(r'<.*?>', '', text)
    # 去除多余空格和换行
    clean = re.sub(r'\s+', ' ', clean).strip()
    # 去除特殊字符
    clean = re.sub(r'[^\u4e00-\u9fa5a-zA-Z0-9,.?!,。?!]', ' ', clean)
    return clean

def _analyze_sentiment(self, text: str) -> float:
    """使用SnowNLP进行情感分析"""
    if not text:
        return 0.5  # 中性
    try:
        return SnowNLP(text).sentiments
    except:
        return 0.5  # 分析失败时返回中性

def get_all_reviews(self, offer_id: str, max_pages: int = 10, has_image: bool = False) -> List[Dict]:
    """
    获取多页评论数据
    :param offer_id: 商品ID
    :param max_pages: 最大页数限制
    :param has_image: 是否只看有图评价
    :return: 所有评论列表
    """
    all_reviews = []
    page = 1
    
    while page <= max_pages:
        logging.info(f"获取第 {page} 页评论")
        result = self.get_item_reviews(
            offer_id=offer_id,
            page=page,
            page_size=50,  # 使用最大页大小减少请求次数
            sort="newest",
            has_image=has_image
        )
        
        if not result or not result["reviews"]:
            break
            
        all_reviews.extend(result["reviews"])
        
        # 检查是否已到最后一页
        if page >= result["pagination"]["total_pages"]:
            break
            
        page += 1
        # 控制请求频率,遵守1688 API的QPS限制
        time.sleep(2)
        
    return all_reviews

def analyze_b2b_reviews(self, reviews: List[Dict]) -> Dict:
    """分析B2B评论数据,生成针对批发采购场景的统计报告"""
    if not reviews:
        return {}
        
    total = len(reviews)
    sentiment_counts = {"positive": 0, "neutral": 0, "negative": 0}
    rating_stats = {
        "product_quality": [],
        "seller_service": [],
        "logistics_speed": [],
        "match_description": []
    }
    tag_counts = {}
    has_image_count = 0
    repeat_buyer_count = 0
    retail_order_count = 0
    total_purchase_quantity = 0
    total_purchase_amount = 0
    
    # B2B场景关键词(与批发采购相关)
    b2b_keywords = {
        "quality": ["质量", "材质", "做工", "品质", "用料"],
        "price": ["价格", "性价比", "便宜", "贵", "优惠"],
        "service": ["服务", "态度", "响应", "沟通", "售后"],
        "logistics": ["物流", "快递", "运输", "速度", "包装"],
        "moq": ["起订量", "批量", "数量", "MOQ"],
        "delivery": ["发货", "交期", "工期", "准时"]
    }
    keyword_counts = {k:0 for k in b2b_keywords}
    
    # 统计基础数据
    for review in reviews:
        # 情感统计
        sentiment = review["sentiment"]["label"]
        sentiment_counts[sentiment] += 1
        
        # 评分统计
        for key in rating_stats:
            if key in review["rating"]:
                rating_stats[key].append(review["rating"][key])
        
        # 标签统计
        for tag in review["tags"]:
            if tag:
                tag_counts[tag] = tag_counts.get(tag, 0) + 1
        
        # 有图评价统计
        if review["images"]:
            has_image_count += 1
            
        # 回头客统计(B2B重要指标)
        if review["trade_info"]["is_repeat_buyer"]:
            repeat_buyer_count += 1
            
        # 零售单统计
        if review["is_retail"]:
            retail_order_count += 1
            
        # 采购量和采购金额统计
        total_purchase_quantity += review["trade_info"]["purchase_quantity"]
        total_purchase_amount += review["trade_info"]["purchase_amount"]
        
        # B2B关键词统计
        content = review["content"].lower()
        for category, kws in b2b_keywords.items():
            for kw in kws:
                if kw in content:
                    keyword_counts[category] += 1
                    break  # 每个类别只计数一次
        
    # 计算平均评分
    avg_ratings = {}
    for key, values in rating_stats.items():
        if values:
            avg_ratings[key] = round(sum(values) / len(values), 1)
        else:
            avg_ratings[key] = 0
    
    # 获取热门标签(前10)
    top_tags = sorted(tag_counts.items(), key=lambda x: x[1], reverse=True)[:10]
    
    # 计算平均采购量和采购金额
    avg_purchase = {
        "quantity": round(total_purchase_quantity / total, 1) if total > 0 else 0,
        "amount": round(total_purchase_amount / total, 2) if total > 0 else 0
    }
    
    return {
        "total_reviews": total,
        "sentiment_distribution": {
            "count": sentiment_counts,
            "percentage": {
                k: round(v / total * 100, 1) for k, v in sentiment_counts.items()
            }
        },
        "average_rating": avg_ratings,
        "image_review_ratio": round(has_image_count / total * 100, 1) if total > 0 else 0,
        "repeat_buyer_ratio": round(repeat_buyer_count / total * 100, 1) if total > 0 else 0,  # 回头客比例(B2B重要指标)
        "retail_order_ratio": round(retail_order_count / total * 100, 1) if total > 0 else 0,  # 零售单比例
        "avg_purchase": avg_purchase,  # 平均采购量和金额
        "total_purchase": {
            "quantity": total_purchase_quantity,
            "amount": total_purchase_amount
        },
        "top_tags": top_tags,
        "b2b_keyword_distribution": keyword_counts
    }

示例调用

if name == "main": # 替换为实际的appkey和appsecret(从1688开放平台获取) APPKEY = "your_appkey" APPSECRET = "your_appsecret" # 替换为目标商品offer_id OFFER_ID = "61234567890"

python 复制代码
# 初始化API客户端
api = Alibaba1688ItemReviewAPI(APPKEY, APPSECRET)

# 方式1:获取单页评论
# review_result = api.get_item_reviews(
#     offer_id=OFFER_ID,
#     page=1,
#     page_size=20,
#     sort="newest",
#     has_image=False
# )

# 方式2:获取多页评论
review_result = api.get_all_reviews(
    offer_id=OFFER_ID,
    max_pages=3,
    has_image=False
)

if isinstance(review_result, dict) and "reviews" in review_result:
    print(f"共获取到 {review_result['pagination']['total_reviews']} 条评论")
    print(f"当前第 {review_result['pagination']['current_page']}/{review_result['pagination']['total_pages']} 页\n")
    
    # 打印前3条评论
    for i, review in enumerate(review_result["reviews"][:3], 1):
        print(f"{i}. 采购商: {review['buyer']['nickname']} ({review['buyer']['region'] or '未知地区'})")
        print(f"   采购信息: {review['trade_info']['purchase_quantity']}件, {review['trade_info']['purchase_amount']}元, {'回头客' if review['trade_info']['is_repeat_buyer'] else '新客户'}")
        print(f"   评分: 质量 {review['rating']['product_quality']}, 服务 {review['rating']['seller_service']}, 物流 {review['rating']['logistics_speed']}")
        print(f"   时间: {review['created_time']}")
        print(f"   内容: {review['content'][:100]}{'...' if len(review['content'])>100 else ''}")
        print(f"   情感: {review['sentiment']['label']} (得分: {review['sentiment']['score']})")
        if review['images']:
            print(f"   图片数: {len(review['images'])}")
        if review['tags']:
            print(f"   标签: {', '.join(review['tags'])}")
        if review['append_comment']:
            print(f"   追评({review['append_comment']['days_after_purchase']}天后): {review['append_comment']['content'][:50]}{'...' if len(review['append_comment']['content'])>50 else ''}")
        print("-" * 100)
        
    # 分析评论
    analysis = api.analyze_b2b_reviews(review_result["reviews"])
    print("\n=== B2B评论分析报告 ===")
    print(f"总评论数: {analysis['total_reviews']}")
    print(f"情感分布: 正面 {analysis['sentiment_distribution']['percentage']['positive']}%, 中性 {analysis['sentiment_distribution']['percentage']['neutral']}%, 负面 {analysis['sentiment_distribution']['percentage']['negative']}%")
    print(f"平均评分: 质量 {analysis['average_rating']['product_quality']}, 服务 {analysis['average_rating']['seller_service']}, 物流 {analysis['average_rating']['logistics_speed']}")
    print(f"回头客比例: {analysis['repeat_buyer_ratio']}%")
    print(f"平均采购量: {analysis['avg_purchase']['quantity']}件, 平均采购金额: {analysis['avg_purchase']['amount']}元")
    print("热门标签:")
    for tag, count in analysis['top_tags']:
        print(f"  {tag}: {count}次")
    print("B2B关键维度提及次数:")
    for category, count in analysis['b2b_keyword_distribution'].items():
        print(f"  {category}: {count}次")
        
elif isinstance(review_result, list):
    # 处理多页评论结果
    print(f"共获取到 {len(review_result)} 条评论")
    
    # 分析评论
    analysis = api.analyze_b2b_reviews(review_result)
    print("\n=== B2B评论分析报告 ===")
    print(f"总评论数: {analysis['total_reviews']}")
    print(f"情感分布: 正面 {analysis['sentiment_distribution']['percentage']['positive']}%, 中性 {analysis['sentiment_distribution']['percentage']['neutral']}%, 负面 {analysis['sentiment_distribution']['percentage']['negative']}%")
    print(f"回头客比例: {analysis['repeat_buyer_ratio']}%")

三、接口调用注意事项

  1. 调用限制与规范
  • QPS 限制:1688 开放平台对评论接口的 QPS 限制通常为 3-5 次 / 秒,低于消费类电商平台
  • 数据权限:评论接口需要申请特定权限,企业账号比个人账号能获取更多数据
  • 分页限制:最多可获取前 50 页评论数据(约 2500 条)
  • 行业差异:不同行业的评论数据结构可能略有差异,尤其是定制类商品
  • 合规使用:评论数据包含采购商信息,需严格遵守隐私保护条款
  1. 常见错误及解决方案 | 错误码 | 说明 | 解决方案 | | --- | ------------- | ----------------------------------------- | | 401 | 未授权或 token 无效 | 重新获取 access_token,检查权限是否正确 | | 403 | 权限不足 | 升级账号类型,申请评论接口的访问权限 | | 404 | 商品不存在或无评论 | 确认 offer_id 是否正确,该商品可能没有评论 | | 429 | 调用频率超限 | 降低调用频率,实现请求限流 | | 500 | 服务器内部错误 | 实现重试机制,最多 3 次,间隔指数退避 | | 110 | 商品 ID 无效 | 检查 offer_id 是否正确,1688 商品 ID 通常为 10-12 位数字 |
  2. 数据解析要点
  • B2B 特有字段:重点关注采购量、采购金额、是否回头客等批发场景特有字段
  • 评分体系:1688 评分通常为 1-5 分,部分字段采用星级制(1-5 星)
  • 地区信息:采购商地区分布对供应链分析有重要价值,需正确解析
  • 图片内容:1688 评论图片多为产品实拍,对质量评估有直接参考价值
  • 合作次数:反映供应商的长期合作稳定性,是 B2B 场景的重要指标

四、应用场景与扩展建议 典型应用场景

  • 供应商评估系统:综合评论数据评估供应商的产品质量和服务水平
  • 采购决策辅助工具:基于其他采购商的评价数据辅助采购决策
  • 供应链风险监控:通过负面评价识别潜在的供应链风险
  • 同类供应商对比:横向对比同类商品供应商的评价数据
  • 市场趋势分析:通过评论内容分析产品需求和市场趋势 扩展建议
  • 实现供应商信用评分模型:结合评论数据构建供应商信用评分体系
  • 开发采购风险预警:基于负面评论关键词自动识别高风险供应商
  • 构建采购量与评价相关性分析:分析采购量与评价之间的关系
  • 开发地区采购偏好分析:分析不同地区采购商的评价差异和偏好
  • 实现长期合作价值评估:基于回头客比例和合作次数评估供应商长期价值
  • 构建多维度供应商雷达图:从质量、服务、物流等维度可视化供应商表现 通过合理使用 1688 item_review 接口,开发者可以构建针对 B2B 场景的供应商评价分析系统,为采购决策和供应链管理提供数据支持。使用时需特别注意 1688 平台的 B2B 特性,关注与批发采购相关的特有数据维度,以获取更有价值的分析结果
相关推荐
用户4099322502126 小时前
如何在 FastAPI 中优雅地模拟多模块集成测试?
后端·ai编程·trae
用户4099322502121 天前
多环境配置切换机制能否让开发与生产无缝衔接?
后端·ai编程·trae
飞哥数智坊1 天前
一个 TRAE 巨好用的隐藏功能:任务完成通知
人工智能·trae
围巾哥萧尘2 天前
围巾哥萧尘:AI编程践行者的技术探索与实践🧣
trae
兵临天下api2 天前
京东 item_review 接口深度分析及 Python 实现
trae
兵临天下api2 天前
京东 item_get_app 接口深度分析及 Python 实现
trae
兵临天下api2 天前
京东 item_video 接口深度分析及 Python 实现
trae
用户4099322502122 天前
如何在 FastAPI 中巧妙覆盖依赖注入并拦截第三方服务调用?
后端·ai编程·trae
倔强的石头1063 天前
Trae x 图片素描MCP一键将普通图片转换为多风格素描效果
低代码·mcp·trae·蓝耘