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 特性,关注与批发采购相关的特有数据维度,以获取更有价值的分析结果
相关推荐
豆包MarsCode8 小时前
Loop Engineering 到底是什么?看这一篇就够了
trae
豆包MarsCode4 天前
如何用 TRAE Work 做用户增长工具
trae
Captaincc11 天前
TRAE AI创造力大赛,正式启动!
trae·vibecoding
沈麽鬼11 天前
今天刚上线!Trae AI 创造力活动来了,程序员 / 设计师直接薅满福利
人工智能·ai编程·trae
沈麽鬼12 天前
别瞎用AI写代码!90%开发者都搞错了AI编程的底层逻辑
人工智能·ai编程·trae
-山中问答-14 天前
【AI智能体工程化实战03】智能体工程化开发环境
人工智能·开发环境·智能体·trae·claude code
掘金酱15 天前
📱 TRAE SOLO 移动端上线征文——“我的第一次移动端AI办公” 评测 | 获奖名单公示
前端·人工智能·trae
木申16 天前
我用瑞幸 CLI 点了一杯咖啡,踩了 3 个坑
人工智能·trae
豆包MarsCode17 天前
运营自媒体太累?用 TRAE Work 立省 80% 工作量
trae
豆包MarsCode22 天前
只需5步,SOLO 实现数据采集到可视化全流程
trae