So scrapen Sie Google-Bewertungen mit Python – Vollständiger Leitfaden 2025
Google-Bewertungen sind eine Goldmine an Kundenfeedback, aber tausende davon manuell zu sammeln? Das ist ineffizient und unpraktisch.
Mit Python können Sie den gesamten Extraktionsprozess automatisieren und in wenigen Stunden tausende Bewertungen sammeln. Dieser Leitfaden führt Sie durch alles – von der grundlegenden Einrichtung bis hin zu produktionsbereiten Scraper, die die Anti-Scraping-Abwehr von Google umgehen.
Am Ende werden Sie verstehen, wie Sie zuverlässige Bewertungs-Scraper erstellen, die Erkennung vermeiden und umsetzbare Kundeninsights in großem Maßstab extrahieren.
Was ist Google-Bewertungen-Scraping?
Google-Bewertungen-Scraping ist die automatisierte Extraktion von Kundenfeedback-Daten aus Google Maps und Google Business-Profilen mithilfe von Python-Skripten.
Wenn Sie Google-Bewertungen scrapen, erfassen Sie:
- Sternbewertungen (1–5 Sterne)
- Bewertungstext (komplette Kundenkommentare)
- Namen und Profile der Rezensenten
- Bewertungsdaten und Zeitstempel
- Antworten von Unternehmen (wenn der Eigentümer geantwortet hat)
- Hilfreiche Abstimmungszahlen
Im Gegensatz zur offiziellen API von Google – die teuer und stark limitiert ist – ermöglicht Scraping den Zugriff auf alle verfügbaren Bewertungen ohne Quoten oder Einschränkungen.
Warum scrapen statt die API von Google zu verwenden?
Die offizielle Places API von Google für Bewertungen hat ernsthafte Einschränkungen:
| Funktion | Offizielle API | Web Scraping |
|---|---|---|
| Bewertungen pro Anfrage | ~10 (nur die neuesten) | Alle verfügbaren |
| Kosten | 7 $ pro 1.000 Anfragen | Kostenlos bis niedrigpreisig |
| Rate-Limits | Maximal 100 Anfragen/Sekunde | Konfigurierbar |
| Wettbewerberbewertungen | ❌ Nein | ✅ Ja |
| Komplexität der Einrichtung | Moderat (Authentifizierung) | Höher (technisch) |
Für Wettbewerbsanalysen, Marktforschung oder die großflächige Datensammlung ist Scraping die praktische Wahl.
Warum Python die beste Sprache für diese Aufgabe ist
Python dominiert das Web Scraping aus drei zentralen Gründen:
1. Reichhaltiges Scraping-Ökosystem
Python hat speziell für Web Scraping entwickelte Bibliotheken:
- Playwright – Moderne, schnelle Browserautomatisierung
- Selenium – Bewährt, maximale Kompatibilität
- BeautifulSoup – Leichtgewichtiges HTML-Parsen
- Scrapy – Unternehmensgerechtes Scraping-Framework
- Pandas – Datenmanipulation und -export
Sie können von rohem HTML zu gereinigtem CSV in einem Skript gelangen.
2. JavaScript-Ausführung
Google-Bewertungen werden dynamisch über JavaScript geladen, nicht im ursprünglichen HTML. Die Automatisierungstools von Python (Playwright, Selenium) führen JavaScript wie ein echter Browser aus, sodass Sie:
- Unendliches Scrollen auslösen
- „Mehr anzeigen“-Schaltflächen klicken
- Warten, bis Inhalte erscheinen
- Mit Seitenelementen interagieren
3. Eingebaute Anti-Detection-Funktionen
Moderne Python-Bibliotheken verfügen über Stealth-Funktionen direkt aus der Box:
# Automatisierungsindikatoren verbergen
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
Diese Flags verhindern, dass Google Ihr Skript als Bot erkennt.
4. Nahtlose Datenverarbeitungspipeline
Mit Python scrapen Sie → reinigen → analysieren → exportieren alles in einem Skript. Kein Werkzeugwechsel erforderlich.
Die Herausforderung: Warum Google Scraping schwierig macht
Google verwendet mehrere Anti-Scraping-Schichten. Das Verständnis dieser hilft Ihnen, robuste Scraper zu erstellen.
1. Dynamisches Inhaltsladen
Google-Bewertungen werden nicht alle auf einmal geladen. Stattdessen:
- Der erste Seitenaufruf zeigt 10–20 Bewertungen
- Zusätzliche Bewertungen werden über AJAX geladen, während Sie scrollen
- Jede Charge erfordert separate Netzwerk-Anfragen
- Der Mechanismus ändert sich häufig
Lösung: Verwenden Sie Browserautomatisierung (Playwright/Selenium), die JavaScript ausführt und das Scrollen simuliert.
2. Aufwendige Bot-Erkennung
Google analysiert:
- Browser-Fingerprinting – Bildschirmauflösung, installierte Schriftarten, Zeitzone
- Verhaltensmuster – Mausbewegungen, Scrollgeschwindigkeit, Klicktiming
- Anfragefrequenz – Erkennung nicht-menschlicher Anfrage-Muster
- IP-Reputation – Markierung verdächtiger Adressen
Lösung: Rotieren Sie Proxys, fügen Sie zufällige Verzögerungen hinzu, verwenden Sie realistische Benutzeragenten.
3. Rate-Limiting und CAPTCHAs
Wenn Sie Google zu stark belasten, werden Sie mit:
- Vorübergehenden IP-Sperren (24–48 Stunden)
- CAPTCHA-Herausforderungen
- Komplettem Zugriffsverbot
- Progressivem Drosseln
Lösung: Implementieren Sie Anfrage-Drosselung (1–3 Sekunden Verzögerung zwischen Aktionen).
4. Ständig evolvierende HTML-Struktur
Google aktualisiert regelmäßig seine Seitenstruktur, wodurch CSS-Selektoren über Nacht brechen.
Lösung: Verwenden Sie mehrere Fallback-Selektoren und attributbasierte Abfragen anstelle von fragilen Klassennamen.
Methode 1: Playwright – Der moderne Ansatz
Playwright ist die empfohlene Wahl für 2025. Es ist schneller als Selenium, hat bessere Anti-Detection-Funktionen und bewältigt moderne, JavaScript-lastige Seiten mühelos.
Playwright einrichten
Erstellen Sie zuerst eine virtuelle Umgebung und installieren Sie die Abhängigkeiten:
# Virtuelle Umgebung erstellen
python -m venv google_scraper
source google_scraper/bin/activate # Unter Windows: google_scraper\Scripts\activate
# Erforderliche Pakete installieren
pip install playwright pandas beautifulsoup4 lxml emoji
# Browser installieren
playwright install chromium
Vollständiger Playwright-Scraper-Code
Hier ist ein produktionsbereiter Scraper, der die Komplexitäten von Google-Bewertungen bewältigt:
from playwright.sync_api import sync_playwright
import pandas as pd
import re
import emoji
import logging
import time
import random
from datetime import datetime
# Logging konfigurieren
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
class GoogleReviewsScraper:
def __init__(self, headless=True):
self.headless = headless
self.reviews_data = []
def clean_text(self, text):
"""Emojis entfernen und Text normalisieren"""
if not text:
return ""
text = emoji.replace_emoji(text, replace='')
text = re.sub(r'\s+', ' ', text).strip()
return text
def random_delay(self, min_delay=1, max_delay=3):
"""Zufällige Verzögerungen hinzufügen, um menschliches Verhalten zu simulieren"""
delay = random.uniform(min_delay, max_delay)
time.sleep(delay)
def initialize_browser(self):
"""Playwright mit Stealth-Einstellungen initialisieren"""
playwright = sync_playwright().start()
browser = playwright.chromium.launch(
headless=self.headless,
args=[
'--disable-blink-features=AutomationControlled',
'--disable-extensions',
'--no-sandbox',
'--disable-dev-shm-usage',
'--disable-gpu'
]
)
context = browser.new_context(
user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
viewport={'width': 1366, 'height': 768}
)
page = context.new_page()
# Webdriver-Eigenschaft verbergen
page.add_init_script("""
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined,
});
""")
return playwright, browser, page
def search_business(self, page, business_name):
"""Nach einem Unternehmen auf Google Maps suchen"""
try:
page.goto("https://www.google.com/maps", wait_until="networkidle")
self.random_delay(2, 4)
# Suchfeld finden und Unternehmensnamen eingeben
search_box = page.locator("input[id='searchboxinput']")
search_box.fill(business_name)
search_box.press("Enter")
# Warten, bis die Ergebnisse geladen sind
page.wait_for_timeout(5000)
logger.info(f"Nach folgendem gesucht: {business_name}")
return True
except Exception as e:
logger.error(f"Fehler bei der Suche nach dem Unternehmen: {e}")
return False
def navigate_to_reviews(self, page):
"""Zur Bewertungssektion navigieren"""
try:
# Nach dem Reiter „Bewertungen“ suchen
reviews_tab = page.get_by_role("tab", name=re.compile("Bewertungen|bewertungen", re.IGNORECASE))
if reviews_tab.is_visible():
reviews_tab.click()
page.wait_for_timeout(3000)
logger.info("Zur Bewertungssektion navigiert")
return True
else:
logger.warning("Bewertungen-Tab nicht gefunden")
return False
except Exception as e:
logger.error(f"Fehler beim Navigieren zu den Bewertungen: {e}")
return False
def scroll_and_load_reviews(self, page, max_reviews=100):
"""Scrollen, um mehr Bewertungen dynamisch zu laden"""
loaded_reviews = 0
scroll_attempts = 0
max_scroll_attempts = 20
while loaded_reviews < max_reviews and scroll_attempts < max_scroll_attempts:
try:
# Nach unten scrollen
page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
self.random_delay(2, 4)
# Aktuelle Bewertungen zählen
current_reviews = page.locator('[data-review-id]').count()
if current_reviews > loaded_reviews:
loaded_reviews = current_reviews
logger.info(f"{loaded_reviews} Bewertungen geladen...")
scroll_attempts = 0 # Zähler zurücksetzen
else:
scroll_attempts += 1
# Versuchen, die Schaltfläche „Mehr Bewertungen“ zu klicken, wenn verfügbar
try:
more_button = page.locator("button:has-text('Mehr'), button:has-text('mehr')")
if more_button.is_visible():
more_button.click()
self.random_delay(2, 3)
except:
pass
except Exception as e:
logger.error(f"Fehler beim Scrollen: {e}")
break
logger.info(f"Laden abgeschlossen. Gesamtbewertungen: {loaded_reviews}")
return loaded_reviews
def extract_review_data(self, page):
"""Individuelle Bewertungsdaten von der geladenen Seite extrahieren"""
reviews = []
try:
review_elements = page.locator('[data-review-id]').all()
for element in review_elements:
try:
review_data = {}
# Rezensentennamen extrahieren
try:
name_element = element.locator('div[class*="name"] span').first
review_data['reviewer_name'] = name_element.inner_text() if name_element.is_visible() else "Anonym"
except:
review_data['reviewer_name'] = "Anonym"
# Bewertung extrahieren
try:
rating_element = element.locator('[role="img"][aria-label*="star"]').first
if rating_element.is_visible():
rating_text = rating_element.get_attribute('aria-label')
rating_match = re.search(r'(\\d+)', rating_text)
review_data['rating'] = int(rating_match.group(1)) if rating_match else None
else:
review_data['rating'] = None
except:
review_data['rating'] = None
# Bewertungstext extrahieren
try:
text_elements = element.locator('span[class*="review-text"], div[class*="review-text"]').all()
review_text = ""
for text_elem in text_elements:
if text_elem.is_visible():
review_text += text_elem.inner_text() + " "
review_data['review_text'] = self.clean_text(review_text.strip())
except:
review_data['review_text'] = ""
# Datum extrahieren
try:
date_element = element.locator('span[class*="date"], div[class*="date"]').first
review_data['review_date'] = date_element.inner_text() if date_element.is_visible() else "Unbekannt"
except:
review_data['review_date'] = "Unbekannt"
# Hilfreiche Anzahl extrahieren
try:
helpful_element = element.locator('[aria-label*="helpful"], [aria-label*="Helpful"]').first
if helpful_element.is_visible():
helpful_text = helpful_element.get_attribute('aria-label')
helpful_match = re.search(r'(\\d+)', helpful_text)
review_data['helpful_count'] = int(helpful_match.group(1)) if helpful_match else 0
else:
review_data['helpful_count'] = 0
except:
review_data['helpful_count'] = 0
# Nur Bewertungen mit tatsächlichem Textinhalt hinzufügen
if review_data['review_text']:
reviews.append(review_data)
except Exception as e:
logger.warning(f"Fehler beim Extrahieren der einzelnen Bewertung: {e}")
continue
logger.info(f"Erfolgreich {len(reviews)} Bewertungen extrahiert")
return reviews
except Exception as e:
logger.error(f"Fehler beim Extrahieren der Bewertungen: {e}")
return []
def scrape_reviews(self, business_name, max_reviews=100):
"""Haupt-Scraping-Methode"""
playwright, browser, page = self.initialize_browser()
try:
# Nach dem Unternehmen suchen
if not self.search_business(page, business_name):
return []
# Zum Bewertungen-Tab navigieren
if not self.navigate_to_reviews(page):
return []
# Bewertungen durch Scrollen laden
self.scroll_and_load_reviews(page, max_reviews)
# Bewertungsdaten extrahieren
reviews = self.extract_review_data(page)
self.reviews_data = reviews
return reviews
except Exception as e:
logger.error(f"Scraping fehlgeschlagen: {e}")
return []
finally:
browser.close()
playwright.stop()
def save_to_csv(self, filename="google_reviews.csv"):
"""Bewertungen in CSV-Datei speichern"""
if self.reviews_data:
df = pd.DataFrame(self.reviews_data)
df['extraction_date'] = datetime.now().isoformat()
df.to_csv(filename, index=False, encoding='utf-8')
logger.info(f"Bewertungen in {filename} gespeichert")
print(f"✅ {len(self.reviews_data)} Bewertungen nach {filename} exportiert")
else:
logger.warning("Keine Bewertungen zum Speichern")
# Anwendungsbeispiel
if __name__ == "__main__":
scraper = GoogleReviewsScraper(headless=False) # Für die Produktion auf True setzen
business_name = "Starbucks Times Square New York"
reviews = scraper.scrape_reviews(business_name, max_reviews=50)
if reviews:
scraper.save_to_csv(f"reviews_{business_name.replace(' ', '_')}.csv")
print(f"✅ Erfolgreich {len(reviews)} Bewertungen gescraped!")
else:
print("❌ Es wurden keine Bewertungen gescraped.")
Wie dieser Scraper funktioniert
1. Stealth-Konfiguration
Der Scraper verbirgt Automatisierungsindikatoren, die Google zur Erkennung von Bots verwendet:
options.add_argument("--disable-blink-features=AutomationControlled")
page.add_init_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
2. Zufällige Verzögerungen
Anstatt Anfragen sofort abzufeuern, wartet der Scraper 1–3 Sekunden zwischen Aktionen, um menschliches Browsing zu simulieren.
3. Dynamisches Scrollen
Er scrollt wiederholt zum Ende der Bewertungssektion, um den unendlichen Scroll-Mechanismus von Google auszulösen und mehr Bewertungen zu laden.
4. Robuste Fehlerbehandlung
Wenn ein Selektor fehlschlägt (weil Google das HTML geändert hat), versucht der Scraper stattdessen Fallback-Selektoren, anstatt abzustürzen.
5. Datenbereinigung
Bewertungen werden gereinigt, um Emojis zu entfernen, Leerzeichen zu normalisieren und qualitativ hochwertige Daten sicherzustellen.
Methode 2: Selenium – Die bewährte Alternative
Während Playwright schneller ist, bleibt Selenium der Goldstandard für Kompatibilität und hat eine riesige Community. Verwenden Sie Selenium, wenn Sie maximale Browserunterstützung benötigen oder bereits eine bestehende Selenium-Infrastruktur haben.
Selenium-Installation
pip install selenium webdriver-manager pandas beautifulsoup4
# ChromeDriver herunterladen (automatisch von webdriver-manager verwaltet)
Vollständige Selenium-Implementierung
```python from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.action_chains import ActionChains from selenium.common.exceptions import TimeoutException, NoSuchElementException import pandas as pd import time import random import re import logging from datetime import datetime
logging.basicConfig(level=logging.INFO) logger = logging.getLogger(name)
class SeleniumGoogleReviewsScraper: def init(self, headless=True): self.headless = headless self.driver = None self.wait = None self.reviews_data = []
def setup_driver(self):
"""Chrome-Treiber konfigurieren und initialisieren"""
options = Options()
if self.headless:
options.add_argument("--headless")
# Anti-Erkennungsmaßnahmen
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
options.add_argument("--disable-extensions")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
options.add_argument("--disable-gpu")
options.add_argument("--window-size=1366,768")
options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36")
self.driver = webdriver.Chrome(options=options)
# Webdriver-Eigenschaft verbergen
self.driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined,});")
self.wait = WebDriverWait(self.driver, 20)
logger.info("Chrome-Treiber initialisiert")
def random_delay(self, min_seconds=1, max_seconds=3):
"""Zufällige Verzögerungen zwischen Aktionen hinzufügen"""
delay = random.uniform(min_seconds, max_seconds)
time.sleep(delay)
def search_google_maps(self, business_name):
"""Nach einem Unternehmen auf Google Maps suchen"""
try:
self.
Bereit loszulegen?
Zugriff auf jedes Google Maps Unternehmen, angereichert mit E-Mails und rechtlichen Daten.
IBLead kostenlos testenVerwandte Artikel
10 Bewährte Tipps, um Kunden zu mehr Google-Bewertungen auf Maps zu bewegen
Erfahren Sie 10 umsetzbare Strategien zur Steigerung von Google Maps-Bewertungen. Timing, Anreize, QR-Codes und Antworttaktiken, die wirklich funktionieren.
7 Kaltakquise-E-Mail-Fehler, die du vermeiden solltest: Beispiele & Vorlagen
Vermeide diese 7 Kaltakquise-E-Mail-Fehler, die die Antwortrate töten. Echte Beispiele, AIDA-Vorlagen und bewährte Lösungen für bessere Ansprache.
ABM Google Maps Daten: Der umfassende strategische Leitfaden
Erfahren Sie, wie ABC Account-Based Marketing Google Maps Daten 208% mehr Umsatz generiert.