亚马逊评论数据采集的「坑」与生产级解决方案(附 Python 完整爬虫代码)

前言
在进行电商数据分析、舆情监控和 AI Agent 选品大模型预训练时,Amazon 评论数据(amazon customer reviews dataset) 是核心语料。然而,随着防爬系统的升级以及 2024 年底亚马逊对评论页面 /product-reviews/ 实施「登录墙」(未登录一律重定向至登录页),传统的 requests + BeautifulSoup 爬虫已经举步维艰。
本文将从底层防爬机制拆解,分享一段能够小规模运行的 Python 评论爬虫代码,深入剖析其在大规模生产环境下的致命缺陷,并提供企业级、高并发的解决方案。
一、学术数据集与商业快照的现状
当我们在寻找亚马逊评论数据集(Amazon Customer Reviews Dataset)时,通常会遇到以下两种选择:
1. 学术开源数据集(UCSD McAuley Lab)
这是目前科研界最常用、最权威的开源数据集。
- 规模:2023 年底发布的最新版本包含 571.54M 条评论,覆盖 33 个品类,跨越 1996 年至 2023 年 9 月。
- 获取渠道:可直接在 Hugging Face 或 AWS S3 上加载。
- 弊端:
- 非商用限制:采用 CC BY-NC 4.0 协议,禁止商业化应用。
- 时效滞后:数据截止至 2023 年 9 月,对于瞬息万变的电商选品和即时差评监控,已经滞后了近三年。
- 无 Customer Says 摘要:该数据集未收录亚马逊 2023 年底推出的 AI 评论总结(Customer Says)。
2. 商业预打包数据集
Bright Data 等平台提供预装的静态数据集交付。虽然提供商业授权,但依然是静态快照(一般为月度或季度更新),无法支撑实时监控(如监控特定竞品 ASIN 的每日新增负面评价)。

二、DIY 亚马逊评论爬虫实现
以下是一段基于 requests 和 BeautifulSoup 编写的亚马逊精选评论采集器。该代码仅用于技术原理演示:
"""
Amazon Reviews 基础采集器 — 仅供技术研究使用
警告:由于登录墙与 anti-bot 检测,本脚本成功率较低,不适合商业化生产。
"""
import requests
from bs4 import BeautifulSoup
import time
import random
import json
from dataclasses import dataclass, asdict
from typing import Optional
@dataclass
class Review:
asin: str
review_id: str
title: str
rating: float
body: str
verified: bool
date: str
helpful_count: int
reviewer_name: str
class AmazonReviewScraper:
BASE_URL = "https://www.amazon.com/dp/{asin}"
# 尝试模拟普通浏览器的 Header
HEADERS = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1"
}
def __init__(self, delay_range=(3, 8)):
self.session = requests.Session()
self.session.headers.update(self.HEADERS)
self.delay_range = delay_range
def _get_page(self, url: str) -> Optional[BeautifulSoup]:
try:
time.sleep(random.uniform(*self.delay_range))
response = self.session.get(url, timeout=15)
# 检测是否跳转到验证码页或登录页
if "ap/signin" in response.url:
print(f"[警告] 触发登录墙,跳转至: {response.url}")
return None
if response.status_code == 503:
print(f"[警告] 503 Service Unavailable,IP已受限")
return None
if response.status_code != 200:
print(f"[错误] HTTP {response.status_code}")
return None
return BeautifulSoup(response.text, "lxml")
except Exception as e:
print(f"[异常] {e}")
return None
def scrape_featured_reviews(self, asin: str) -> list[Review]:
url = self.BASE_URL.format(asin=asin)
soup = self._get_page(url)
if not soup:
return []
reviews = []
review_divs = soup.select("[data-hook='review']")
# 兼容备用选择器
if not review_divs:
review_divs = soup.select(".review")
for div in review_divs:
try:
review_id = div.get("id", "")
if not review_id:
continue
# 星级评分
rating_elem = div.select_one("[data-hook='review-star-rating'] span")
rating_text = rating_elem.get_text() if rating_elem else "0"
rating = float(rating_text.split()[0]) if rating_text else 0.0
# 标题与正文
title = div.select_one("[data-hook='review-title'] span:last-child").get_text(strip=True)
body = div.select_one("[data-hook='review-body'] span").get_text(strip=True)
# 评论日期
date = div.select_one("[data-hook='review-date']").get_text(strip=True)
# 购买验证标记
verified = div.select_one("[data-hook='avp-badge']") is not None
# 觉得有用人数
helpful_elem = div.select_one("[data-hook='helpful-vote-statement']")
helpful_text = helpful_elem.get_text(strip=True) if helpful_elem else "0"
helpful_count = 0
if "One person" in helpful_text:
helpful_count = 1
elif helpful_text:
try:
helpful_count = int(helpful_text.split()[0].replace(",", ""))
except:
pass
reviewer_name = div.select_one(".a-profile-name").get_text(strip=True)
reviews.append(Review(
asin=asin, review_id=review_id, title=title, rating=rating,
body=body, verified=verified, date=date, helpful_count=helpful_count,
reviewer_name=reviewer_name
))
except Exception as e:
print(f"[解析单条失败] {e}")
return reviews
if __name__ == "__main__":
scraper = AmazonReviewScraper()
# 示例 ASIN
data = scraper.scrape_featured_reviews("B08N5WRWNW")
print(json.dumps([asdict(r) for r in data], indent=2, ensure_ascii=False))
三、为什么这段代码无法用于大规模生产环境?
当你想把上述脚本用于商业决策或高频任务时,你会在 72 小时内遇到以下瓶颈:
- 登录墙拦截(Catastrophic Block):
亚马逊在/product-reviews/接口上实施了强登录要求。未登录用户只能读取详情页自带的极少数「精选评论」(一般只有 8 条左右)。如果你想通过翻页收集几千条历史评论,该脚本会彻底失效。 - TLS/JA3 指纹识别:
亚马逊使用 Cloudflare/Akamai 或自建的 WAF,会在 TCP/TLS 握手阶段收集你的客户端 JA3 指纹。Pythonrequests的默认密码套件顺序具有极高的识别性,即使你的 User-Agent 伪装得再逼真,WAF 依然可以直接 503 阻断。 - Customer Says AI 摘要缺失:
现代选品分析高度依赖 Amazon 的 AI 摘要接口,这是通过独立的 GraphQL 异步接口渲染的,单纯抓取 HTML 文档无法拿到该核心字段。 - 代理 IP 的天价开销:
亚马逊对 IP 段的信誉评分非常严格。机房 IP (Datacenter IP) 瞬间被封,迫使你使用昂贵的住宅代理 IP (Residential IP),按流量计费($3-$15/GB)。高并发采集评论页会产生无法承受的代理账单。

四、生产级选型方案
针对以上痛点,企业级开发中通常会采用专业的代理托管 API,这里以市场上主流的方案做一对比:
| 维度 | DIY 爬虫 | Bright Data API | Oxylabs API | Pangolinfo Amazon Review API |
|---|---|---|---|---|
| 反反爬维护 | 需专人持续更新指纹与选择器 | 托管维护 | 托管维护 | 托管维护 |
| Customer Says | ❌ 无法抓取 | 部分支持 | 部分支持 | ✅ 完整支持 |
| 实时性 | ❌ 经常被封 | ✅ 实时 | ✅ 实时 | ✅ 分钟级实时 |
| 接入成本 | 极高 (研发与调试) | 较高 ($0.75-3.00/1K) | 较高 ($0.50-1.35/1K) | 极低 (按量付费,性价比高) |
代码演练:使用 Pangolinfo API 获取完整评论
采用专业 API 后,无需再编写繁琐的选择器,更不需要自己维护复杂的住宅代理池:
import requests
class PangolReviewClient:
API_URL = "https://api.pangolinfo.com/v1/amazon/reviews"
def __init__(self, api_key: str):
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
def fetch_reviews(self, asin: str, page: int = 1) -> dict:
payload = {
"asin": asin,
"marketplace": "US",
"page": page,
"sort_by": "recent"
}
response = requests.post(self.API_URL, json=payload, headers=self.headers, timeout=20)
return response.json()
# 使用示例
if __name__ == "__main__":
client = PangolReviewClient(api_key="YOUR_API_KEY")
result = client.fetch_reviews("B08N5WRWNW")
# 打印返回的 AI 摘要
print("AI Summary (Customer Says):", result.get("customer_says"))
# 打印第一条评论
if result.get("reviews"):
print("First Review:", result["reviews"][0])
Pangolinfo API 屏蔽了底层的验证码突破、TLS 混淆以及登录态模拟,返回已经格式化完毕的 JSON 数据。
对于需要将数据流直接输送给大语言模型或 Dify 工作流的团队,Pangolinfo 还提供了原生的 Amazon Data MCP 协议支持,让 AI Agent 可以免去二次封装,实现分钟级的数据检索。
结论
- 纯学术研究:优先选择 UCSD McAuley Lab 开源的数据集,免费、量大,但需做去偏斜处理。
- 小规模尝试:可基于 Cpython 使用
curl_cffi配合动态住宅代理进行实验。 - 商业级生产线:自建爬虫团队的研发与代理维护成本远超想象。直接接入类似 Pangolinfo Amazon Review API的托管数据采集解决方案,能够显著降低 TCO(总体拥有成本)并提升系统稳定性。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)