Dlaczego Scrape Recenzje produktów w skali?
Przeglądy produktów są jednym z najcenniejszych źródeł danych w handlu elektronicznym. Ujawniają one sentymenty klientów, problemy związane z jakością produktów, wymagania dotyczące funkcji oraz konkurencyjne pozycjonowanie - informacje, których żadne inne źródło danych nie może dostarczyć. W skali, dane przeglądowe umożliwiają:
- Analiza sentymentów: Śledź, co klienci czują do swoich produktów i produktów konkurentów w czasie.
- Rozwój produktu: Identyfikacja powtarzających się skarg i odpowiedzi na zapytania w tysiącach recenzji.
- Wywiad konkurencyjny: Zrozumienie mocnych i słabych stron konkurencji na podstawie własnych słów klientów.
- Badania rynku: Odkryj niezaspokojone potrzeby i pojawiające się trendy poprzez analizę wzorców przeglądu w różnych kategoriach.
- Monitorowanie jakości: Wykrywanie problemów związanych z jakością produktów na wczesnym etapie poprzez monitorowanie tendencji w przeglądzie.
Wyzwaniem jest to, że dane przeglądowe są rozpowszechniane na wielu platformach (Amazon, Walmart, Best Buy, Trustpilot, Google), każdy z różnych struktur i ochrony anty-bot. Przeglądy skracające w skali wymagają strategii specyficznych dla platformy i solidnej infrastruktury proxy. Podstawowe wzory e-commerce scrating, zobacz nasz Przewodnik do zeskrobywania danych e-commerce.
Przegląd struktury danych pomiędzy platformami
| Platforma | Pola przeglądu | Paginacja | Poziom anty-bot |
|---|---|---|---|
| Amazon | Ocena, tytuł, tekst, data, zweryfikowane, pomocne głosy | Na podstawie strony (10 / strona) | Wysoki |
| Walmart Przewodniczący | Ocena, tytuł, tekst, data, źródło przedłożenia | Offset- based API | Średni |
| Best Buy | Ocena, tytuł, tekst, data, pomocna / niepomocna | API oparte na stronie | Średni |
| Trustpilot | Ocena, tytuł, tekst, data, odpowiedź | Na podstawie strony | Średnie |
| Zakupy Google | Ocena, tekst, data, źródło | Na podstawie przewijania | Wysoki |
Konfiguracja Proxy dla Scraping Review
Przegląd scrating wiąże się z nawigacji strony, co oznacza utrzymanie sesji w wielu próbach. Przylepne sesje ProxyHat są idealne do tego wzoru.
Ustawienia 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:8080Do przeglądu scrating, stosować lepkie sesje podczas przeglądania przez wszystkie przeglądy dla jednego produktu, a rotacja żądanie podczas poruszania się między różnymi produktami. To naśladuje naturalne zachowanie przeglądania gdzie użytkownik czyta wiele stron recenzji dla jednego produktu przed przejściem do następnego.
Wdrażanie Pythona
Oto wieloplatformowy scrapper recenzji za pomocą Python SDK 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 NoneWieloplatformowy Kolekcjoner Przeglądu
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)}")Wdrażanie Node.js
Node.js scrapper recenzji za pomocą Węzeł 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));
});Postępowanie z paginacją w skali
Paginacja przeglądowa jest jednym z największych wyzwań w drapaniu na dużą skalę.
Amazon Pagination Strategy
Amazon ogranicza strony recenzji do 10 recenzji każdy i zazwyczaj pokazuje do 500 stron (5000 recenzji). Dla produktów z większą ilością recenzji, użyj parametrów filtra do segmentacji:
# 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 productZarządzanie sesją w przypadku paginacji
Każda strona przeglądu produktu powinna korzystać z własnej sesji lepkiej. Po zakończeniu jednego produktu i przejściu do następnego, utworzyć nową sesję z innym IP.
| Faza | Strategia proxy | Uzasadnienie |
|---|---|---|
| Znalezienie produktów | Rotacja na żądanie | Niezależne wyszukiwanie, nie wymaga sesji |
| Przeglądy stron | Nalepka sesja na produkt | Ten sam IP na wszystkich stronach wygląda naturalnie |
| Pomiędzy produktami | Nowa sesja / IP | Świeża tożsamość dla każdego produktu |
Przygotowanie danych do analizy sentymentów
Tekst przeglądu surowego wymaga wstępnego przetwarzania przed analizą sentymentów.
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
),
}Skalowanie do milionów recenzji
Kiedy lista docelowa rośnie do tysięcy produktów na wielu platformach, architektura ma znaczenie.
Architektura oparta na kolejkach
- Użyj kolejki wiadomości (Redis, RabbitMQ) do zarządzania listą produktów i dystrybucji pracy wśród pracowników.
- Każdy pracownik zajmuje się jednym produktem na raz: paginate poprzez wszystkie opinie, wyniki przechowywania, przejść do następnego produktu.
- Oddzielne kolejki na platformę w celu przestrzegania różnych limitów stawek.
Strategia składowania
- Przechowuj surowy HTML w pamięci obiektowej (S3) do ponownego przetwarzania przy zmianie parserów.
- Przechowuj przeglądane opinie w PostgreSQL z pełnym wyszukiwaniem tekstu do analizy.
- Użyj dedukcji w oparciu o ID przeglądu lub hash, aby uniknąć przechowywania duplikatów na ponownych scrapes.
Rozdrapywanie przyrostowe
W celu stałego monitorowania, nie trzeba ponownie zeskrobywać wszystkie opinie za każdym razem. Sortuj według najnowszych i zatrzymać, gdy trafisz recenzję już zebrane. To dramatycznie zmniejsza wykorzystanie proxy i przyspiesza kolekcję.
Key takeaway: Sortuj opinie przez najnowszy pierwszy i przestań scrating po trafieniu wcześniej zebrane treści. To zamienia pełną zmianę w przyrostową aktualizację.
Najlepsze praktyki
- Użyj lepkich sesji dla paginacji: Utrzymanie tego samego IP na wszystkich stronach przeglądowych dla jednego produktu, aby uniknąć wywołania antybotowego wykrywania.
- Limity stawek przestrzegania: 2- 5 sekund opóźnienia między stronami, dłuższe opóźnienia między produktami. Różne platformy mają różne tolerancje.
- Obsługa pustych stron: Pusta strona recenzji oznacza, że osiągnąłeś koniec. Nie próbuj więcej stron.
- Sprawdzić jakość danych: Sprawdź strony CAPTCHA, puste treści i duplikuj opinie w swoim rurociągu.
- Stosowanie proxy mieszkaniowe: Istotne dla Amazon i innych silnie chronionych platform.
- Przechowywać stopniowo: Przetwarzaj i przechowuj recenzje jak je skrobiesz, nie w jednej partii na końcu.
Key Takeaways
- Dane z przeglądu dostarczają unikalnej, konkurencyjnej inteligencji, której nie oferuje żadne inne źródło danych.
- Różne platformy wymagają różnych strategii skrobania - budować modułowe skrobaczki na platformie.
- Używaj lepkich sesji do przeglądu paginacji i rotacji na żądanie między produktami.
- Sortuj przez najnowszy pierwszy i zatrzymać się na wcześniej zebrane opinie dla efektywnego drapania przyrostowego.
- Wstępny przegląd tekstu do analizy sentymentów: czyste, odduplikowane i wydobyć kluczowe zwroty.
- Stosowanie ProxyHat 's residential proxy z geologicznym celem zapewnienia wiarygodnego dostępu do przeglądów stron we wszystkich platformach.
Gotowy do zbierania danych z przeglądu? Zobacz Amazon scrating guide dla platformów- szczegóły i nasze Przewodnik do zeskrobywania danych e-commerce dla pełnej strategii. Sprawdź przy użyciu proxy w Python oraz przy użyciu proxy w Node.js wzorców wdrażania.






