Por que raspar o produto em escala?
As revisões de produtos são uma das fontes de dados mais valiosas no comércio eletrônico. Eles revelam sentimentos do cliente, problemas de qualidade do produto, solicitações de recursos e posicionamento competitivo — informações que nenhuma outra fonte de dados pode fornecer. Na escala, os dados de revisão permitem:
- Análise dos sentimentos: Acompanhe como os clientes se sentem sobre seus produtos e produtos concorrentes ao longo do tempo.
- Desenvolvimento de produtos: Identifique reclamações recorrentes e solicitações de recursos em milhares de avaliações.
- Inteligência competitiva: Compreender os pontos fortes e fracos dos seus próprios clientes.
- Investigação de mercado: Descubra necessidades não satisfeitas e tendências emergentes analisando padrões de revisão entre categorias.
- Monitorização da qualidade: Detecte problemas de qualidade do produto precocemente, monitorando as tendências de sentimentos.
O desafio é que os dados de revisão estão espalhados por várias plataformas (Amazon, Walmart, Best Buy, Trustpilot, Google), cada uma com diferentes estruturas e proteções anti-bot. Resenhas de raspagem em escala requer estratégias específicas de plataforma e infraestrutura proxy robusta. Para padrões de raspagem de e-commerce fundacionais, consulte Guia de raspagem de dados do comércio electrónico.
Analisar a Estrutura dos Dados nas Plataformas
| Plataforma | Campos de Revisão | Paginação | Nível Anti- Bot |
|---|---|---|---|
| Amazonas | Classificação, título, texto, data, votos verificados, úteis | Baseada na página (10/página) | Alta |
| Walmart | Classificação, título, texto, data, fonte de submissão | API baseada em deslocamento | Médio |
| Melhor Compra | Classificação, título, texto, data, útil/inajudante | API baseada na página | Médio |
| Piloto Trust | Classificação, título, texto, data, resposta | Baseado na página | Média Baixa |
| Google Compras | Classificação, texto, data, fonte | Baseada em rolagem | Alta |
Configuração do Proxy para Raspar Revisão
Raspar revisão envolve navegação paginada, o que significa manter sessões em várias solicitações. As sessões pegajosas do ProxyHat são ideais para este padrão.
Configuração do ProxyHat
# Per-request rotation for initial product lookups
http://USERNAME:PASSWORD@gate.proxyhat.com:8080
# Sticky session for paginating through reviews of one product
http://USERNAME-session-rev001:PASSWORD@gate.proxyhat.com:8080
# Geo-targeted for region-specific review pages
http://USERNAME-country-US:PASSWORD@gate.proxyhat.com:8080Para avaliar raspagem, use sessões pegajosas ao paginar através de todas as avaliações para um único produto, e rotação por pedido ao se mover entre diferentes produtos. Isso imita o comportamento natural de navegação onde um usuário lê várias páginas de comentários para um produto antes de se mudar para o próximo.
Implementação em Python
Aqui está um raspador de revisão multi-plataforma usando O SDK Python do ProxyHatName.
Amazon Review Scraper
import requests
from bs4 import BeautifulSoup
import json
import time
import random
from dataclasses import dataclass
from datetime import datetime
PROXY_URL = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
USER_AGENTS = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
]
@dataclass
class Review:
platform: str
product_id: str
rating: float
title: str
text: str
date: str
author: str
verified: bool
helpful_votes: int
def scrape_amazon_reviews(asin, max_pages=10):
"""Scrape all reviews for an Amazon product."""
reviews = []
session_id = f"rev-{asin}-{random.randint(1000, 9999)}"
proxy = f"http://USERNAME-session-{session_id}:PASSWORD@gate.proxyhat.com:8080"
session = requests.Session()
session.proxies = {"http": proxy, "https": proxy}
session.headers.update({
"User-Agent": random.choice(USER_AGENTS),
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
})
for page in range(1, max_pages + 1):
url = (f"https://www.amazon.com/product-reviews/{asin}"
f"?pageNumber={page}&sortBy=recent")
try:
response = session.get(url, timeout=30)
if response.status_code != 200:
break
if "captcha" in response.text.lower():
print(f"CAPTCHA on page {page}, switching session")
break
soup = BeautifulSoup(response.text, "html.parser")
review_divs = soup.find_all("div", {"data-hook": "review"})
if not review_divs:
break
for div in review_divs:
review = parse_amazon_review(div, asin)
if review:
reviews.append(review)
print(f"Page {page}: {len(review_divs)} reviews (total: {len(reviews)})")
time.sleep(random.uniform(2, 5))
except requests.RequestException as e:
print(f"Error on page {page}: {e}")
break
return reviews
def parse_amazon_review(div, asin):
"""Parse a single Amazon review element."""
try:
rating_el = div.find("i", {"data-hook": "review-star-rating"})
rating = float(rating_el.get_text().split(" ")[0]) if rating_el else None
title_el = div.find("a", {"data-hook": "review-title"})
title = title_el.get_text(strip=True) if title_el else ""
body_el = div.find("span", {"data-hook": "review-body"})
text = body_el.get_text(strip=True) if body_el else ""
date_el = div.find("span", {"data-hook": "review-date"})
date_str = date_el.get_text(strip=True) if date_el else ""
author_el = div.find("span", {"class": "a-profile-name"})
author = author_el.get_text(strip=True) if author_el else ""
verified = bool(div.find("span", {"data-hook": "avp-badge"}))
helpful_el = div.find("span", {"data-hook": "helpful-vote-statement"})
helpful = 0
if helpful_el:
text_h = helpful_el.get_text()
if "one" in text_h.lower():
helpful = 1
else:
nums = [int(s) for s in text_h.split() if s.isdigit()]
helpful = nums[0] if nums else 0
return Review(
platform="amazon",
product_id=asin,
rating=rating,
title=title,
text=text,
date=date_str,
author=author,
verified=verified,
helpful_votes=helpful,
)
except Exception:
return NoneColetor de Revisão Multi- Plataforma
class ReviewCollector:
"""Collect reviews from multiple platforms for a product."""
def __init__(self):
self.scrapers = {
"amazon": scrape_amazon_reviews,
}
def collect_all(self, product_ids: dict) -> list[Review]:
"""
Collect reviews from all platforms.
product_ids: {"amazon": "B0CHX3QBCH", "walmart": "12345"}
"""
all_reviews = []
for platform, product_id in product_ids.items():
if platform in self.scrapers:
print(f"\nScraping {platform} reviews for {product_id}")
reviews = self.scrapers[platform](product_id)
all_reviews.extend(reviews)
print(f"Collected {len(reviews)} reviews from {platform}")
time.sleep(random.uniform(5, 10))
return all_reviews
def to_dataframe(self, reviews: list[Review]):
"""Convert reviews to a pandas DataFrame for analysis."""
import pandas as pd
return pd.DataFrame([vars(r) for r in reviews])
# Usage
collector = ReviewCollector()
reviews = collector.collect_all({
"amazon": "B0CHX3QBCH",
})
print(f"\nTotal reviews collected: {len(reviews)}")Implementação Node.js
Um raspador de revisão Node.js usando O Nó do ProxyHat SDK.
const axios = require("axios");
const cheerio = require("cheerio");
const { HttpsProxyAgent } = require("https-proxy-agent");
function getProxy(sessionId = null) {
if (sessionId) {
return `http://USERNAME-session-${sessionId}:PASSWORD@gate.proxyhat.com:8080`;
}
return "http://USERNAME:PASSWORD@gate.proxyhat.com:8080";
}
async function scrapeAmazonReviews(asin, maxPages = 10) {
const reviews = [];
const sessionId = `rev-${asin}-${Math.floor(Math.random() * 9000 + 1000)}`;
const agent = new HttpsProxyAgent(getProxy(sessionId));
for (let page = 1; page <= maxPages; page++) {
const url = `https://www.amazon.com/product-reviews/${asin}?pageNumber=${page}&sortBy=recent`;
try {
const { data } = await axios.get(url, {
httpsAgent: agent,
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
"Accept-Language": "en-US,en;q=0.9",
},
timeout: 30000,
});
if (data.toLowerCase().includes("captcha")) {
console.log(`CAPTCHA on page ${page}`);
break;
}
const $ = cheerio.load(data);
const reviewDivs = $('[data-hook="review"]');
if (reviewDivs.length === 0) break;
reviewDivs.each((_, el) => {
const $el = $(el);
const ratingText = $el.find('[data-hook="review-star-rating"]').text();
const rating = parseFloat(ratingText.split(" ")[0]) || null;
reviews.push({
platform: "amazon",
productId: asin,
rating,
title: $el.find('[data-hook="review-title"]').text().trim(),
text: $el.find('[data-hook="review-body"]').text().trim(),
date: $el.find('[data-hook="review-date"]').text().trim(),
author: $el.find(".a-profile-name").text().trim(),
verified: $el.find('[data-hook="avp-badge"]').length > 0,
});
});
console.log(`Page ${page}: ${reviewDivs.length} reviews (total: ${reviews.length})`);
await new Promise((r) => setTimeout(r, 2000 + Math.random() * 3000));
} catch (err) {
console.error(`Error page ${page}: ${err.message}`);
break;
}
}
return reviews;
}
// Usage
scrapeAmazonReviews("B0CHX3QBCH", 5).then((reviews) => {
console.log(`Collected ${reviews.length} reviews`);
console.log(JSON.stringify(reviews.slice(0, 2), null, 2));
});Manuseamento da Paginação na Escala
A paginação de revisão é um dos maiores desafios na raspagem em larga escala.
Estratégia de Paginação da Amazônia
Amazon limita as páginas de revisão a 10 avaliações cada e normalmente mostra até 500 páginas (5.000 avaliações). Para produtos com mais revisões, use parâmetros de filtro para segmentar:
# Filter by star rating to get more reviews
star_filters = [
"one_star", "two_star", "three_star",
"four_star", "five_star"
]
for star in star_filters:
url = (f"https://www.amazon.com/product-reviews/{asin}"
f"?filterByStar={star}&pageNumber={page}")
# This lets you access more reviews per productGerenciamento de Sessão para Paginação
A paginação de revisão de cada produto deve usar sua própria sessão pegajosa. Quando você terminar um produto e passar para o próximo, crie uma nova sessão com um IP diferente.
| Fase | Estratégia de Proxy | Justificação |
|---|---|---|
| Encontrar produtos | Rotação por pedido | Procuras independentes, nenhuma sessão necessária |
| Revisão paginativa | Sessão fixa por produto | O mesmo IP entre páginas parece natural |
| Entre produtos | Nova sessão/IP | Identidade fresca para cada produto |
Preparação de dados para análise de sentimentos
Texto de revisão cru precisa de pré-processamento antes da análise do sentimento.
import re
from collections import Counter
def clean_review_text(text):
"""Clean review text for analysis."""
# Remove HTML entities
text = re.sub(r'&\w+;', ' ', text)
# Remove excessive whitespace
text = re.sub(r'\s+', ' ', text).strip()
# Remove very short reviews (likely not useful)
if len(text) < 20:
return None
return text
def extract_key_phrases(reviews, min_frequency=3):
"""Extract frequently mentioned phrases from reviews."""
from collections import Counter
import re
words = []
for review in reviews:
if review.text:
# Simple bigram extraction
tokens = re.findall(r'\b\w+\b', review.text.lower())
for i in range(len(tokens) - 1):
bigram = f"{tokens[i]} {tokens[i+1]}"
words.append(bigram)
return Counter(words).most_common(50)
def aggregate_sentiment(reviews):
"""Calculate aggregate sentiment metrics."""
if not reviews:
return {}
ratings = [r.rating for r in reviews if r.rating]
return {
"total_reviews": len(reviews),
"avg_rating": sum(ratings) / len(ratings) if ratings else 0,
"rating_distribution": {
str(i): len([r for r in reviews if r.rating == i])
for i in range(1, 6)
},
"verified_pct": (
len([r for r in reviews if r.verified]) / len(reviews) * 100
if reviews else 0
),
}Escalar para Milhões de Comentários
Quando sua lista de alvos cresce para milhares de produtos em várias plataformas, a arquitetura importa.
Arquitetura Baseada na Fila
- Use uma fila de mensagens (Redis, RabbitMQ) para gerenciar a lista de produtos e distribuir trabalho entre os trabalhadores.
- Cada trabalhador lida com um produto de cada vez: paginar através de todos os comentários, armazenar resultados, passar para o próximo produto.
- Separar filas por plataforma para respeitar diferentes limites de taxa.
Estratégia de armazenamento
- Armazene HTML bruto no armazenamento de objetos (S3) para reprocessamento quando os analisadores mudarem.
- Armazene comentários em PostgreSQL com pesquisa de texto completo para análise.
- Usar desduplicação com base no ID de revisão ou hash para evitar armazenar duplicatas em re-crapes.
Raspamento incremental
Para monitoramento contínuo, você não precisa re-crape todos os comentários todas as vezes. Ordenar por mais recente e parar quando você bater uma revisão que você já coletou. Isso reduz drasticamente o uso do proxy e acelera a coleta.
Key takeaway: Ordenar comentários por mais novo primeiro e parar de raspar quando você bater conteúdo coletado anteriormente. Isso transforma um re-crape completo em uma atualização incremental.
Melhores Práticas
- Usar sessões pegajosas para paginação: Mantenha o mesmo IP em páginas de revisão para um único produto para evitar a detecção anti-bot.
- Limites da taxa de respeito: 2-5 atrasos de segundo entre páginas, atrasos mais longos entre produtos. Diferentes plataformas têm tolerâncias diferentes.
- Lidar com páginas vazias: Uma página de revisão vazia significa que você chegou ao fim. Não continue tentando mais páginas.
- Validar a qualidade dos dados: Verifique páginas CAPTCHA, conteúdo vazio e revisões duplicadas no seu pipeline.
- Utilização proxies residenciais: Essencial para a Amazon e outras plataformas fortemente protegidas.
- Armazenar incrementalmente: Processar e armazenar comentários como você raspa-los, não em um lote no final.
Tiras de Chaves
- Os dados de revisão fornecem inteligência competitiva única que nenhuma outra fonte de dados oferece.
- Diferentes plataformas requerem diferentes estratégias de raspagem — construir raspadores modulares por plataforma.
- Use sessões pegajosas para avaliar a paginação e rotação por solicitação entre produtos.
- Ordenar por primeiro mais novo e parar em avaliações previamente coletadas para raspagem incremental eficiente.
- Texto de revisão pré-processo para análise de sentimentos: limpo, deduplicar e extrair frases-chave.
- Utilização Proxies residenciais do ProxyHat com geo-alvo para acesso confiável a páginas de revisão em todas as plataformas.
Pronto para começar a coletar dados de revisão? Veja o nosso Guia de raspagem da Amazônia para detalhes específicos da plataforma e nossa Guia de raspagem de dados do comércio electrónico para a estratégia completa. Verificar usando proxies em Python e usando proxies em Node.js para padrões de implementação.






