¿Por qué Scrape Comentarios de Productos en Scale?
Las reseñas de productos son una de las fuentes de datos más valiosas del comercio electrónico. Ellos revelan el sentimiento del cliente, problemas de calidad de producto, solicitudes de características y posicionamiento competitivo - información que ninguna otra fuente de datos puede proporcionar. A escala, los datos de revisión permiten:
- Análisis de la sensibilidad: Seguimiento de cómo se sienten los clientes sobre sus productos y productos de los competidores con el tiempo.
- Desarrollo de productos: Identificar quejas recurrentes y presentar peticiones en miles de exámenes.
- Inteligencia competitiva: Comprender las fortalezas y debilidades de los competidores de sus propias palabras.
- Investigación del mercado: Descubra las necesidades no satisfechas y las tendencias emergentes analizando patrones de revisión en distintas categorías.
- Supervisión de calidad: Detectar problemas de calidad de los productos rápidamente mediante la vigilancia de las tendencias sentimentales de revisión.
El reto es que los datos de revisión se difunden a través de múltiples plataformas (Amazon, Walmart, Best Buy, Trustpilot, Google), cada una con diferentes estructuras y protecciones antibot. Los exámenes a escala requieren estrategias específicas de plataforma e infraestructura proxy robusta. Para patrones de raspado de comercio electrónico fundamental, vea nuestra Guía de intercambio electrónico de datos.
Review Data Structure Across Platforms
| Plataforma | Review Fields | Pagination | Anti-Bot Level |
|---|---|---|---|
| Amazon | Valoración, título, texto, fecha, verificado, votos útiles | Page-based (10/page) | Alto |
| Walmart | Valoración, título, texto, fecha, fuente de presentación | API basada en activos | Mediana |
| Mejor compra | Valoración, título, texto, fecha, útil/sin ayuda | API basada en la página | Mediana |
| Trustpilot | Valoración, título, texto, fecha, respuesta | Basado en la página | Low-Medium |
| Google Shopping | Valoración, texto, fecha, fuente | Scroll-based | Alto |
Configuración proxy para el cambio de revisión
El desguace de la revisión implica la navegación paginada, lo que significa mantener sesiones a través de múltiples solicitudes. Las sesiones pegajosas de ProxyHat son ideales para este patrón.
Configuración 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 revisar el desguace, utilice sesiones pegajosas al paginar a través de todas las opiniones para un solo producto, y la rotación por solicitud al moverse entre diferentes productos. Este imita el comportamiento de navegación natural donde un usuario lee múltiples páginas de reseñas para un producto antes de moverse a la siguiente.
Python Implementation
Aquí hay un raspador de revisión multiplataforma utilizando El SDK Python de ProxyHat.
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 NoneMulti-Platform Review Collector
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)}")Node.js Implementation
Un raspador de revisión Node.js utilizando Nodo de 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));
});Paginación de manipulación en escala
La paginación de revisión es uno de los mayores desafíos en el raspado de revisión a gran escala.
Amazon Pagination Strategy
Amazon limita las páginas de revisión a 10 reseñas cada una y normalmente muestra hasta 500 páginas (5.000 reseñas). Para productos con más opiniones, utilice parámetros de filtro a segmento:
# 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 productSession Management for Pagination
La paginación de revisión de cada producto debe usar su propia sesión pegajosa. Cuando termine un producto y se mueva a la siguiente, cree una nueva sesión con una IP diferente.
| Fase | Proxy Strategy | Razón |
|---|---|---|
| Encontrar productos | Rotación por vehículo | Consultas independientes, no es necesario celebrar un período de sesiones |
| Opiniones de pacientes | Sesión pegajosa por producto | El mismo IP en páginas se ve natural |
| Entre productos | Nuevo período de sesiones/IP | Identidad fresca para cada producto |
Preparación de datos para el análisis de la sensibilidad
El texto de revisión cruda necesita preprocesamiento antes del análisis de sentimientos.
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
),
}Escalando a Millones de Comentarios
Cuando su lista de destino crece a miles de productos en múltiples plataformas, la arquitectura importa.
Arquitectura basada en la cola
- Utilice una cola de mensaje (Redis, RabbitMQ) para gestionar la lista de productos y distribuir trabajo a través de los trabajadores.
- Cada trabajador maneja un producto a la vez: paginar a través de todas las opiniones, almacenar resultados, pasar al siguiente producto.
- Separar colas por plataforma para respetar diferentes límites de tarifas.
Estrategia de almacenamiento
- Almacene HTML crudo en almacenamiento de objetos (S3) para reprocesar cuando los analizadores cambian.
- Almacene opiniones analizadas en PostgreSQL con búsqueda de texto completo para el análisis.
- Utilice la deduplicación basada en ID de revisión o hash para evitar almacenar duplicados en re-scrapes.
Incremental Scraping
Para el monitoreo continuo, usted no necesita re-scrape todas las críticas cada vez. Ordenar por más reciente y parar cuando usted golpeó una revisión que ya ha recogido. Esto reduce drásticamente el uso proxy y acelera la colección.
Key takeaway: Sort reviews by newest first and stop scraping when you hit previously collected content. Esto convierte una recuperación completa en una actualización incremental.
Buenas prácticas
- Use sesiones pegajosas para la paginación: Mantenga la misma IP en las páginas de revisión para un solo producto para evitar la detección de antibots.
- Limitaciones de la tasa de respeto: 2-5 segundos retrasos entre páginas, demoras más largas entre productos. Las diferentes plataformas tienen diferentes tolerancias.
- Paginas vacías: Una página de revisión vacía significa que has llegado al final. No siga intentando más páginas.
- Valorar la calidad de los datos: Compruebe las páginas de CAPTCHA, el contenido vacío y duplicar las reseñas en su oleoducto.
- Uso proxies residenciales: Esencial para Amazon y otras plataformas fuertemente protegidas.
- Store incrementalmente: Procesar y almacenar las reseñas mientras las raspa, no en un lote al final.
Key Takeaways
- Los datos de revisión proporcionan una inteligencia competitiva única que ninguna otra fuente de datos ofrece.
- Las diferentes plataformas requieren diferentes estrategias de raspado: construir raspadores modulares por plataforma.
- Use sesiones pegajosas para revisar paginación y rotación por solicitud entre productos.
- Ordenar por más reciente primero y parar en revisiones previamente recolectadas para un correcto raspado incremental.
- Revisión previa del texto para el análisis de sentimientos: limpio, deduplicado y extraer frases clave.
- Uso Los proxies residenciales de ProxyHat con geo-targeting para el acceso confiable a las páginas de revisión en todas las plataformas.
¿Listo para empezar a recopilar datos de revisión? Vea nuestro Amazon scraping guide para detalles específicos de plataforma y nuestros Guía de intercambio electrónico de datos para la estrategia completa. Check usando proxies en Python y usando proxies en Node.js para las pautas de aplicación.






