Warum Scrape Produktbewertungen auf Scale?
Produktbewertungen sind eine der wertvollsten Datenquellen im E-Commerce. Sie zeigen Kundenzufriedenheit, Produktqualitätsfragen, Feature-Anfragen und wettbewerbsfähige Positionierung – Informationen, die keine andere Datenquelle bieten kann. Die Überprüfungsdaten ermöglichen im Maßstab:
- Sentiment-Analyse: Verfolgen Sie, wie sich Kunden im Laufe der Zeit über Ihre Produkte und Konkurrenten freuen.
- Produktentwicklung: Identifizieren Sie wiederkehrende Beschwerden und Feature-Anfragen in Tausenden von Bewertungen.
- Wettbewerbsfähige Intelligenz: Verstehen Sie die Stärken und Schwächen ihrer Kunden aus eigenen Worten.
- Marktforschung: Entdecken Sie ungeeignete Bedürfnisse und aufstrebende Trends, indem Sie Bewertungen Muster in verschiedenen Kategorien analysieren.
- Qualitätskontrolle: Erkennen Sie frühzeitig Produktqualitätsfragen, indem Sie die Einschätzungstrends überwachen.
Die Herausforderung besteht darin, dass die Überprüfungsdaten auf mehreren Plattformen (Amazon, Walmart, Best Buy, Trustpilot, Google) verteilt werden, die jeweils unterschiedliche Strukturen und Anti-Bot-Schutz aufweisen. Scraping-Bewertungen im Maßstab erfordern plattformspezifische Strategien und robuste Proxy-Infrastruktur. Für grundlegende E-Commerce-Schrottmuster, siehe unsere e-Commerce Daten-Schrottführer.
Überprüfen Sie Data Structure Across Plattformen
| Plattform | Testfelder | Pagination | Anti-Bot Level |
|---|---|---|---|
| Amazon | Bewertung, Titel, Text, Datum, überprüft, hilfreiche Stimmen | Page-based (10/page) | hoch |
| Walmart | Bewertung, Titel, Text, Datum, Eingabequelle | Offsetbasierte API | Mittel |
| Bester Verkauf | Bewertung, Titel, Text, Datum, hilfreich/nicht hilfreich | Seitebasierte API | Mittel |
| Trustpilot | Bewertung, Titel, Text, Datum, Antwort | Seite | Low-Medium |
| Google Shopping | Bewertung, Text, Datum, Quelle | Scroll-basiert | hoch |
Proxy-Konfiguration für Review Scraping
Überprüfung Schrott beinhaltet paginierte Navigation, was bedeutet, Sitzungen über mehrere Anfragen zu halten. ProxyHats klebrige Sitzungen sind ideal für dieses Muster.
ProxyHat Setup
# 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:8080Verwenden Sie klebrige Sitzungen, wenn Sie sich durch alle Bewertungen für ein einzelnes Produkt paginieren, und per-Request-Rotation, wenn Sie sich zwischen verschiedenen Produkten bewegen. Dieses mimiert natürliches Surfverhalten, bei dem ein Benutzer mehrere Seiten von Bewertungen für ein Produkt liest, bevor er zum nächsten bewegt.
Implementierung von Python
Hier ist ein Multi-Plattform-Review-Schrotter mit ProxyHat's Python SDK.
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 Implementierung
Ein Node.js Review-Schrotter mit ProxyHat's Node 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));
});Umgang mit Pagination im Maßstab
Review pagination ist eine der größten Herausforderungen bei der groß angelegten Überprüfungsschabung.
Amazon Pagination Strategie
Amazon limitiert Seiten auf jeweils 10 Bewertungen und zeigt in der Regel bis zu 500 Seiten (5.000 Bewertungen). Für Produkte mit mehr Bewertungen verwenden Sie Filterparameter zu Segment:
# 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 für Pagination
Jedes Produkt Überprüfung Pagination sollte eine eigene klebrige Sitzung verwenden. Wenn Sie ein Produkt beenden und zum nächsten wechseln, erstellen Sie eine neue Sitzung mit einer anderen IP.
| Phase | Proxy-Strategie | Begründung |
|---|---|---|
| Produkte finden | Per-Request Rotation | Unabhängige Lookups, keine Sitzung erforderlich |
| Paginating Bewertungen | Sticking Session pro Produkt | Die gleiche IP auf den Seiten sieht natürlich aus |
| Zwischen den Produkten | Neue Sitzung/IP | Frische Identität für jedes Produkt |
Daten für die Bewertungsanalyse vorbereiten
Der Text der Rohüberprüfung muss vor der sentimentalen Analyse vor der Verarbeitung erfolgen.
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
),
}Skalierung von Millionen von Bewertungen
Wenn Ihre Zielliste auf Tausende von Produkten auf mehreren Plattformen wächst, ist Architektur wichtig.
Queue-Based Architecture
- Verwenden Sie eine Nachrichtenwarteschlange (Redis, RabbitMQ), um die Produktliste zu verwalten und die Arbeit über die Arbeitnehmer zu verteilen.
- Jeder Arbeiter behandelt ein Produkt zu einer Zeit: paginate durch alle Bewertungen, speichern Ergebnisse, bewegen Sie zum nächsten Produkt.
- Separate Warteschlangen pro Plattform, um verschiedene Geschwindigkeitsgrenzen zu respektieren.
Speicherstrategie
- Speichern Sie rohes HTML in Objektspeicher (S3) für die Wiederaufarbeitung, wenn Parsers ändern.
- Parsed Bewertungen in PostgreSQL mit Volltextsuche nach Analyse speichern.
- Verwenden Sie Deduplizierung basierend auf Überprüfung ID oder Hash, um Doppelte auf Re-Scrapes zu speichern.
Incremental Scraping
Für die laufende Überwachung müssen Sie nicht jedes Mal alle Bewertungen neu kratzen. Sortieren nach neuesten und stoppen, wenn Sie eine Bewertung getroffen haben Sie bereits gesammelt. Dies reduziert die Proxy-Nutzung und beschleunigt die Sammlung.
Key Takeaway: Sortieren Sie Bewertungen nach neuestem zuerst und stoppen Sie Schrott, wenn Sie zuvor gesammelte Inhalte getroffen. Dies verwandelt eine vollständige Re-Scrape in ein inkrementelles Update.
Best Practices
- Verwenden Sie klebrige Sitzungen für Pagination: Bewahren Sie das gleiche IP über Überprüfungsseiten für ein einzelnes Produkt, um Anti-Bot-Erkennung auszulösen.
- Grenzwerte für die Prüfung: 2-5 zweite Verzögerungen zwischen den Seiten, längere Verzögerungen zwischen den Produkten. Verschiedene Plattformen haben unterschiedliche Toleranzen.
- leere Seiten austragen: Eine leere Review-Seite bedeutet, dass Sie das Ende erreicht haben. Versuchen Sie nicht mehr Seiten.
- Gültige Datenqualität: Überprüfen Sie CAPTCHA-Seiten, leere Inhalte und doppelte Bewertungen in Ihrer Pipeline.
- Verwendung Wohngebiete: Wesentlich für Amazon und andere stark geschützte Plattformen.
- Inkrementell speichern: Bearbeiten und speichern Sie Bewertungen, wenn Sie sie abkratzen, nicht in einer Charge am Ende.
Schlüsselanhänger
- Testdaten bieten einzigartige wettbewerbsfähige Intelligenz, die keine andere Datenquelle bietet.
- Verschiedene Plattformen erfordern unterschiedliche Abstreifstrategien – modulare Abstreifer pro Plattform.
- Verwenden Sie klebrige Sitzungen zur Überprüfung Pagination und Per-Request Rotation zwischen Produkten.
- Sortieren nach neueste zuerst und stoppen Sie bei zuvor gesammelten Bewertungen für effiziente Inkremental-Schrott.
- Text zur Einschätzung der Einschätzung vorbearbeiten: sauber, deduplizieren und Schlüsselphrasen extrahieren.
- Verwendung ProxyHat's Wohn-Proxies mit Geo-Targeting für einen zuverlässigen Zugriff auf Webseiten auf allen Plattformen.
Bereit zum Sammeln von Überprüfungsdaten? Sehen Sie uns Amazon Schrottführer für plattformspezifische Details und unsere e-Commerce Daten-Schrottführer für die volle Strategie. Überprüfung mit Proxies in Python und mit Proxies in Node.js für Umsetzungsmuster.






