Zurück zum Blog
Anleitungen & How-tos2026-02-12·7 Min. Lesezeit

So scrapen Sie Google-Bewertungen mit Python – Vollständiger Leitfaden 2025

Von Ibrahim DemolCEO IBLeadAktualisiert am 26. März 2026

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 testen