一、前言
淘宝商品评论数据是电商数据分析的"金矿"------用户真实反馈、产品痛点、竞品对比都隐藏其中。但淘宝的反爬机制堪称国内电商平台最严密之一,sign签名动态加密 、滑块验证 、行为风控层层设防。
本文基于2024-2025年最新技术实践,详解两种主流抓取方案:PC端网页解析 (适合小规模)与移动端接口逆向(适合大规模),并提供完整的Python工程代码与反爬对抗策略。
二、技术方案选型
| 方案 | 适用场景 | 技术难度 | 稳定性 | 数据完整性 |
|---|---|---|---|---|
| PC端网页解析 | 小规模测试/临时抓取 | ⭐⭐ | 中(易触发验证码) | 中等(需渲染JS) |
| 移动端API逆向 | 大规模生产环境 | ⭐⭐⭐⭐ | 高(需维护签名算法) | 高(纯JSON数据) |
| RPA自动化 | 超小规模/精准抓取 | ⭐⭐⭐ | 低(依赖页面结构) | 完整但效率低 |
推荐选择 :生产环境务必采用移动端接口逆向方案,直接调用淘宝内部API,绕过前端渲染,效率提升10倍以上。
三、方案一:PC端网页解析(入门向)
3.1 接口定位与抓包
打开Chrome开发者工具(F12),进入商品详情页,滚动到评论区:
-
筛选请求 :Network面板筛选
XHR/Fetch,关键词过滤rate/comment/list -
定位接口:典型URL格式:
https://rate.taobao.com/feedRateList.do?itemId=123456789&sellerId=987654321¤tPage=1&pageSize=20&_t=1689200000000 -
关键参数识别:
-
itemId:商品ID(URL中提取) -
sellerId:卖家ID(页面源码中查找) -
currentPage:分页页码 -
_t:时间戳(防缓存) -
sign:动态签名(核心加密参数)
-
3.2 基础抓取代码
python
import requests
import re
import time
import random
from fake_useragent import UserAgent
class TaobaoWebScraper:
def __init__(self):
self.ua = UserAgent()
self.session = requests.Session()
self.session.headers.update({
"User-Agent": self.ua.random,
"Referer": "https://item.taobao.com/",
"Accept": "application/json, text/javascript, */*; q=0.01",
"Accept-Language": "zh-CN,zh;q=0.9",
"X-Requested-With": "XMLHttpRequest"
})
def extract_item_id(self, product_url):
"""从商品URL提取itemId"""
patterns = [
r"item\.taobao\.com/item\.htm\?.*id=(\d+)",
r"detail\.tmall\.com/item\.htm\?.*id=(\d+)",
]
for pattern in patterns:
match = re.search(pattern, product_url)
if match:
return match.group(1)
raise ValueError("无法提取商品ID")
def fetch_comments(self, item_id, page=1):
"""获取单页评论"""
api_url = "https://rate.taobao.com/feedRateList.do"
params = {
"itemId": item_id,
"currentPage": page,
"pageSize": 20,
"_t": int(time.time() * 1000), # 动态时间戳
"callback": f"jsonp_{int(time.time())}" # JSONP回调
}
try:
response = self.session.get(api_url, params=params, timeout=10)
response.raise_for_status()
# 解析JSONP格式:jsonp_xxx({...})
json_str = re.search(r'jsonp_\d+\((.*)\)', response.text)
if json_str:
import json
data = json.loads(json_str.group(1))
return self._parse_comments(data)
return None
except Exception as e:
print(f"请求失败: {e}")
return None
def _parse_comments(self, data):
"""解析评论数据结构"""
if data.get("ret", [""])[0] != "SUCCESS::调用成功":
return None
comments = []
for item in data.get("data", {}).get("comments", []):
comments.append({
"user": item.get("userNick", ""),
"content": self._clean_text(item.get("content", "")),
"date": item.get("commentTime", ""),
"star": item.get("star", 0),
"useful": item.get("useful", 0),
"images": item.get("images", [])
})
return comments
def _clean_text(self, text):
"""清洗文本(去除HTML标签和表情)"""
text = re.sub(r'<[^>]+>', '', text)
text = re.sub(r'[\U00010000-\U0010ffff]', '', text, flags=re.UNICODE)
return text.strip()
# 使用示例
if __name__ == "__main__":
scraper = TaobaoWebScraper()
item_id = scraper.extract_item_id("https://item.taobao.com/item.htm?id=123456789")
for page in range(1, 4):
comments = scraper.fetch_comments(item_id, page)
if comments:
print(f"第{page}页获取{len(comments)}条评论")
time.sleep(random.uniform(2, 5)) # 随机延迟防封
3.3 PC端反爬对抗
淘宝PC端风控特征:
-
Cookie验证 :需携带有效的
cna/tracknick等Cookie -
Referer校验:必须来自商品详情页
-
请求频率:单IP每秒>1次即可能触发滑块
应对策略:
-
使用
requests.Session()维持Cookie会话 -
插入随机延迟(2-5秒/请求)
-
配合代理IP池轮换(推荐付费代理如站大爷、阿布云)
四、方案二:移动端API逆向(生产级)
这是业界主流方案,通过抓包淘宝APP获取内部API,数据为纯净JSON,无需渲染,且反爬阈值更高。
4.1 抓包环境搭建
工具链:
-
Charles/Fiddler:HTTPS抓包(需安装系统根证书)
-
Jadx/GDA:APK反编译分析加密逻辑
-
Frida:动态调试Hook加密函数(进阶)
抓包步骤:
-
手机配置Charles代理(同WiFi下)
-
淘宝APP浏览商品评论
-
Charles中筛选
mtop.taobao.detail或rate相关请求 -
关键发现:淘宝使用MTOP协议(阿里巴巴移动端统一网关)
4.2 MTOP协议核心机制
移动端接口典型特征:
GET https://h5api.m.taobao.com/h5/mtop.taobao.rate.detaillist.get/6.0/
Headers:
x-m-appkey: 12574478
x-m-timestamp: 1700000000000
x-m-sign: xxxxxxxxxxxxxxxx ← 核心加密参数
x-m-c-trace-id: xxx
Cookie: _m_h5_tk=xxxxx; _m_h5_tk_enc=xxxxx
签名生成逻辑(通过Jadx逆向得出):
4.3 完整逆向实现代码
4.4 关键逆向技巧
1. Token维护机制:
-
_m_h5_tk有效期约24小时,需定时刷新 -
通过访问
https://h5.m.taobao.com/首页自动更新Cookie
2. 签名算法追踪:
-
若淘宝升级加密(如改为HMAC-SHA256),需重新反编译APK
-
使用Frida Hook
com.taobao.wireless.security.adapter.JNICLibrary.doCommandNative函数动态获取签名
3. 设备指纹模拟:
Python
复制
# 模拟淘宝APP设备指纹
headers = {
"x-umidtoken": "Txxx_xxx", # 通过算法生成或从真机提取
"x-wap-profile": "https://img.taobao.com/...",
"x-m-biz-code": "taobao",
"x-m-biz-data": "..." # 设备环境加密数据
}
五、反爬对抗实战策略
5.1 风控触发场景与应对
表格
复制
| 风控等级 | 触发特征 | 应对策略 |
|---|---|---|
| 初级 | 要求滑动验证码 | 接入打码平台(如超级鹰)或使用Selenium过滑块 |
| 中级 | 返回"访问频繁"或空数据 | 切换代理IP + 增加请求间隔(>5秒) |
| 高级 | 账号封禁/设备拉黑 | 更换设备指纹 + 使用新账号 + 降低频率 |
5.2 代理IP池架构
Python
复制
import redis
from concurrent.futures import ThreadPoolExecutor
class ProxyManager:
def __init__(self):
self.redis_client = redis.Redis(host='localhost', port=6379, db=0)
self.proxy_key = "taobao:proxies"
def validate_proxy(self, proxy):
"""验证代理可用性(访问淘宝测试接口)"""
test_url = "https://h5api.m.taobao.com/h5/mtop.taobao.wireless.home.load/1.0/"
try:
resp = requests.get(test_url, proxy={"https": proxy}, timeout=5)
return resp.status_code == 200
except:
return False
def get_valid_proxy(self):
"""从Redis获取可用代理"""
proxy = self.redis_client.srandmember(self.proxy_key)
return proxy.decode() if proxy else None
def feedback_proxy(self, proxy, success):
"""代理质量反馈(失败次数过多则移除)"""
if not success:
self.redis_client.hincrby("taobao:proxy_failures", proxy, 1)
if self.redis_client.hget("taobao:proxy_failures", proxy) > b"5":
self.redis_client.srem(self.proxy_key, proxy)
5.3 数据存储与监控
python
from sqlalchemy import create_engine, Column, String, Integer, Text, DateTime
from sqlalchemy.orm import sessionmaker
import pandas as pd
class CommentStorage:
def __init__(self, db_url="sqlite:///taobao_comments.db"):
self.engine = create_engine(db_url)
self.Session = sessionmaker(bind=self.engine)
self._init_tables()
def save_comments(self, item_id, comments):
"""批量保存评论"""
session = self.Session()
try:
for c in comments:
session.add(CommentModel(
item_id=item_id,
user_nick=c['user'],
content=c['content'],
star=c['star'],
comment_time=c['date'],
raw_data=json.dumps(c)
))
session.commit()
except Exception as e:
session.rollback()
raise e
finally:
session.close()
def export_to_excel(self, item_id, filepath):
"""导出分析报表"""
session = self.Session()
comments = session.query(CommentModel).filter_by(item_id=item_id).all()
df = pd.DataFrame([c.to_dict() for c in comments])
# 简单情感分析
df['sentiment'] = df['content'].apply(self._simple_sentiment)
df.to_excel(filepath, index=False)
def _simple_sentiment(self, text):
"""基于关键词的简单情感判断"""
positive_words = ['好评', '满意', '喜欢', '推荐', '不错']
negative_words = ['差评', '失望', '垃圾', '假货', '退货']
score = sum(1 for w in positive_words if w in text) - \
sum(1 for w in negative_words if w in text)
return "positive" if score > 0 else "negative" if score < 0 else "neutral"
六、合规与法律边界
⚠️ 重要声明:以下行为可能违反《淘宝平台服务协议》及《网络安全法》:
-
禁止行为:
-
破解淘宝加密算法用于商业竞品分析
-
高频抓取导致淘宝服务器负载异常
-
抓取用户隐私信息(如匿名买家真实身份)
-
将数据用于刷单、炒信等违规场景
-
-
合规建议:
-
仅采集公开可见的评论内容
-
请求频率控制在单IP每秒<1次,日请求<1000次
-
数据仅用于个人学习、学术研究或内部产品优化
-
考虑接入淘宝官方开放平台API(需申请权限)
-
七、总结与进阶
本文详解了淘宝评论抓取的两大技术路径:
-
PC端方案:适合快速验证,但受限于反爬,仅适合小规模
-
移动端逆向:生产环境首选,需持续维护签名算法,配合代理池可实现日采10万+评论
进阶方向:
-
实时采集:基于WebSocket监听淘宝直播评论(需逆向直播API)
-
图文分析:使用OCR提取评论图片中的文字(如快递单、产品瑕疵图)
-
知识图谱:构建用户-商品-评论关系图,挖掘水军账号