Zurück zum Blog
Anleitungen
Raluca PenciucLast updated on Mar 31, 202613 min read

Wie man Yelp mit Python scrappt: Bewertungen, Listen und LLM-fähige Datenpipelines

Wie man Yelp mit Python scrappt: Bewertungen, Listen und LLM-fähige Datenpipelines
Kurzfassung: Dieser Leitfaden führt Sie Schritt für Schritt durch die Erstellung eines vollständigen Yelp-Scrapers in Python und behandelt Suchergebnisse, Unternehmensdaten und Bewertungen anhand von funktionierendem Code. Außerdem lernen Sie, wie Sie mit Anti-Bot-Schutzmaßnahmen umgehen, Daten in CSV oder JSON exportieren und gescrapte Bewertungen zur Stimmungsanalyse in ein LLM einspeisen – etwas, das kein anderes Yelp-Scraping-Tutorial behandelt.

Einleitung

Yelp verfügt über eine der umfangreichsten Sammlungen lokaler Unternehmensdaten im Internet: Bewertungen, Rezensionen, Öffnungszeiten, Kategorien, Fotos und mehr – alles verknüpft mit Millionen von Unternehmen in Hunderten von Städten. Wenn Sie verstehen möchten, wie man Yelp programmgesteuert scrapt, ist Python das praktischste Werkzeug für diese Aufgabe.

Web-Scraping von Yelp bedeutet, strukturierte Daten aus den öffentlichen Seiten von Yelp (typischerweise Suchergebnisse, einzelne Unternehmensprofile und Nutzerbewertungen) mithilfe von HTTP-Anfragen und HTML-Parsing zu extrahieren, anstatt manuell zu kopieren und einzufügen. Ganz gleich, ob Sie ein Dashboard für Wettbewerbsanalysen erstellen, die Stimmung in Bewertungen überwachen oder Leads aus lokalen Verzeichnissen generieren – der zugrunde liegende Arbeitsablauf ist derselbe: die Seite abrufen, den HTML-Code parsen und die Ergebnisse speichern.

Dieses Tutorial bietet Ihnen ein vollständiges End-to-End-Projekt. Sie beginnen mit dem Scraping von Suchergebnissen, gehen dann zur Extraktion von Unternehmensdetails über und widmen sich anschließend der Sammlung von Bewertungen mit Paginierung. Anschließend behandeln wir Anti-Bot-Strategien, asynchrone Skalierung, Datenexport und einen einzigartigen Workflow zur Weiterleitung von Yelp-Daten an ein LLM für die automatisierte Zusammenfassung. Jeder Code-Schnipsel ist lauffähig, und jeder Abschnitt erklärt neben dem „Wie“ auch das „Warum“.

Warum Yelp scrapen? Geschäftsanwendungsfälle, für die es sich lohnt

Bevor wir uns mit dem Code befassen, lohnt es sich zu verstehen, warum Yelp-Daten so wertvoll sind. Yelp ist nicht nur eine Bewertungsseite, sondern ein strukturiertes Verzeichnis mit detaillierten Signalen, die anderswo nur schwer zu finden sind. Hier sind die Anwendungsfälle, die das Scraping von Yelp lohnenswert machen.

Wettbewerbsanalyse und Benchmarking. Wenn Sie ein Restaurant, einen Friseursalon oder ein anderes lokales Dienstleistungsunternehmen betreiben, verraten Ihnen Yelp-Bewertungen genau, was Kunden an Ihren Mitbewerbern lieben (und hassen). Durch das Scraping von Sternebewertungen, der Anzahl der Bewertungen und der Antwortraten innerhalb einer Kategorie können Sie Ihr Unternehmen mit der lokalen Konkurrenz vergleichen.

Bewertungsüberwachung und Stimmungsanalyse. Die Verfolgung von Bewertungen über einen längeren Zeitraum hinweg deckt Trends auf: Beschweren sich Kunden in diesem Quartal häufiger über Wartezeiten? Ausgelesene Yelp-Bewertungen fließen direkt in Stimmungsanalyse-Pipelines ein und liefern Ihnen quantitative Signale aus qualitativem Feedback.

Lead-Generierung. Yelp-Einträge enthalten Firmennamen, Telefonnummern, Adressen und Kategorien. Für B2B-Vertriebsteams, die lokale Unternehmen ansprechen (z. B. Anbieter von Kassensystemen oder Marketingagenturen), ist ein Yelp-Scraper eine Maschine zur Lead-Generierung.

Lokale SEO-Audits. Der Vergleich der Vollständigkeit Ihres Yelp-Eintrags (Fotos, Öffnungszeiten, Kategorien, Antwortrate) mit den bestplatzierten Wettbewerbern deckt Lücken in Ihrer lokalen Präsenz auf.

Marktforschung und Standortauswahl. Sie eröffnen einen neuen Standort? Scrapen Sie Yelp, um die Dichte der Wettbewerber, durchschnittliche Bewertungen und das Bewertungsvolumen nach Stadtviertel zu erfassen. Diese Daten fließen direkt in Modelle zur Standortauswahl ein.

Der Punkt ist, dass das Erlernen des Scrapings von Yelp keine akademische Übung ist. Die Daten sind die Grundlage für echte Geschäftsentscheidungen.

Voraussetzungen und Projekteinrichtung

Sie benötigen Python 3.9 oder höher. Erstellen Sie ein neues Projektverzeichnis und installieren Sie die wichtigsten Abhängigkeiten:

pip install requests beautifulsoup4 lxml

Hier ist die Funktion der einzelnen Pakete:

  • requests: verarbeitet HTTP-Anrufe an die Seiten von Yelp
  • beautifulsoup4: parst den zurückgegebenen HTML-Code in eine navigierbare Baumstruktur
  • lxml: ein schneller HTML/XML-Parser, den BeautifulSoup als Backend verwendet

Für spätere Abschnitte benötigen Sie außerdem:

pip install httpx openai

httpx bietet dir asynchrone HTTP-Unterstützung für paralleles Scraping, und openai (oder einen beliebigen LLM-Client) treibt die Daten-zu-Erkenntnisse-Pipeline an, die wir am Ende erstellen werden.

Erstellen Sie eine scraper.py Datei und fügen Sie die Standard-Importe hinzu:

import requests
from bs4 import BeautifulSoup
import csv
import json
import time
import random

Das ist Ihre Grundlage. Jeder der folgenden Abschnitte baut auf dieser Konfiguration auf.

Scraping von Yelp-Suchergebnissen

Der erste Schritt bei jedem Yelp-Scraping-Projekt ist das Sammeln von Brancheneinträgen aus Suchergebnisseiten. Wenn Sie auf Yelp nach etwas wie „Pizza“ in „New York, NY“ suchen, folgt die URL einem vorhersehbaren Muster:

https://www.yelp.com/search?find_desc=pizza&find_loc=New+York%2C+NY&start=0

Der start -Parameter steuert die Paginierung und erhöht sich für jede neue Seite um 10. Erstellen wir einen Scraper, der Einträge über mehrere Seiten hinweg sammelt.

def scrape_search_results(query, location, max_pages=5):
    results = []
    headers = {
        "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",
        "Accept-Language": "en-US,en;q=0.9",
    }

    for page in range(max_pages):
        offset = page * 10
        url = (
            f"https://www.yelp.com/search?"
            f"find_desc={query}&find_loc={location}&start={offset}"
        )
        response = requests.get(url, headers=headers)

        if response.status_code != 200:
            print(f"Blocked or error on page {page}: {response.status_code}")
            break

        soup = BeautifulSoup(response.text, "lxml")
        cards = soup.select('[data-testid="serp-ia-card"]')

        if not cards:
            break

        for card in cards:
            name_tag = card.select_one("a.css-19v1rkv")
            rating_tag = card.select_one('[aria-label*="star rating"]')
            review_count_tag = card.select_one("span.css-chan6m")

            results.append({
                "name": name_tag.get_text(strip=True) if name_tag else None,
                "url": "https://www.yelp.com" + name_tag["href"] if name_tag else None,
                "rating": rating_tag["aria-label"] if rating_tag else None,
                "review_count": review_count_tag.get_text(strip=True) if review_count_tag else None,
            })

        time.sleep(random.uniform(2, 5))

    return results

Ein paar Dinge, die du bei der Selektorstrategie beachten solltest. Die Klassennamen von Yelp werden dynamisch generiert (diese css-* Zeichenfolgen), sodass sie sich zwischen den Bereitstellungen ändern können. Die data-testid Attribute sind in der Regel stabiler, da sie für interne Tests verwendet werden. Überprüfen Sie Ihre Selektoren immer anhand der Live-Seite, bevor Sie sie in großem Maßstab ausführen.

Yelp stellt auch einen Such-Snippet-Endpunkt bereit, der JSON direkt zurückgeben kann, wodurch das Parsen von HTML vollständig entfallen würde. Da sich die Verfügbarkeit und Struktur dieses Endpunkts jedoch ohne Vorankündigung ändern kann, ist der oben beschriebene HTML-Ansatz die zuverlässige Basis.

Die Paginierungsschleife erhöht start bei jeder Iteration um 10 und stoppt, wenn keine weiteren Eintragskarten mehr gefunden werden. Die zufällige Verzögerung zwischen den Anfragen ist unerlässlich, um Ratenbeschränkungen zu vermeiden – darauf gehen wir später noch im Detail ein.

Extrahieren von Unternehmensdetails aus Yelp-Eintragseiten

Suchergebnisse liefern Ihnen Namen und Bewertungen, aber die einzelnen Unternehmensseiten enthalten die wirklich wertvollen Daten: vollständige Adresse, Telefonnummer, Öffnungszeiten, Kategorien, Preisklasse und mehr. So extrahieren Sie Unternehmensdaten aus Yelp-Listing-Seiten.

def scrape_business_details(business_url, headers):
    response = requests.get(business_url, headers=headers)
    if response.status_code != 200:
        return None

    soup = BeautifulSoup(response.text, "lxml")

    def safe_text(selector):
        tag = soup.select_one(selector)
        return tag.get_text(strip=True) if tag else None

    # Extract business_id from meta or script tags for API use
    meta_biz = soup.select_one('meta[name="yelp-biz-id"]')
    business_id = meta_biz["content"] if meta_biz else None

    details = {
        "business_id": business_id,
        "name": safe_text("h1"),
        "rating": None,
        "phone": safe_text('[data-testid="phone-info"] p'),
        "address": safe_text("address"),
        "categories": [],
        "hours": {},
    }

    # Star rating from aria-label
    rating_el = soup.select_one('[aria-label*="star rating"]')
    if rating_el:
        details["rating"] = rating_el["aria-label"]

    # Categories
    cat_links = soup.select('span.css-1xfc281 a')
    details["categories"] = [a.get_text(strip=True) for a in cat_links]

    # Hours table
    hours_rows = soup.select("table.hours-table tr")
    for row in hours_rows:
        cols = row.select("td, th")
        if len(cols) >= 2:
            day = cols[0].get_text(strip=True)
            time_range = cols[1].get_text(strip=True)
            details["hours"][day] = time_range

    return details

Die business_id aus dem Meta-Tag extrahierte ID ist besonders nützlich. Yelp verwendet diese ID intern, und sie kann als Schlüssel zur Duplikatsbereinigung oder zum Aufbau von URLs für Bewertungs-Endpunkte dienen. Wenn Sie Yelp-Unternehmensdaten in großem Umfang scrapen, ist eine stabile Kennung pro Unternehmen entscheidend für die Aufrechterhaltung sauberer Datensätze.

Beachten Sie, dass die HTML-Struktur von Yelp je nach Unternehmenskategorie leicht variiert. Eine Restaurantseite verfügt über einen Menübereich, die Seite eines Klempners hingegen nicht. Ihr Parsing-Code sollte fehlende Elemente elegant behandeln (genau das tut der safe_text Helper). Überprüfen Sie jeden Rückgabewert des Selectors, bevor Sie versuchen, auf Attribute oder Text zuzugreifen.

Yelp-Bewertungen in großem Umfang scrapen

Bewertungen sind oft der wertvollste Teil der Yelp-Datenextraktion. Jede Bewertung enthält den Namen des Bewerters, die Sternebewertung, das Datum und den vollständigen Text – genau das, was du für die Stimmungsanalyse oder Wettbewerbsbeobachtung benötigst.

Yelp paginiert Bewertungen mit einem start Abfrageparameter und zeigt in der Regel 10 Bewertungen pro Seite an. Hier ist ein Scraper, der die Bewertungsseiten durchläuft:

def scrape_reviews(business_url, max_pages=10, headers=None):
    reviews = []

    for page in range(max_pages):
        offset = page * 10
        url = f"{business_url}?start={offset}&sort_by=date_desc"
        response = requests.get(url, headers=headers or {})

        if response.status_code != 200:
            print(f"Review page {page} returned {response.status_code}")
            break

        soup = BeautifulSoup(response.text, "lxml")
        review_containers = soup.select('[data-testid="review"]')

        if not review_containers:
            break

        for container in review_containers:
            user_tag = container.select_one("a.css-19v1rkv")
            rating_tag = container.select_one('[aria-label*="star rating"]')
            date_tag = container.select_one("span.css-chan6m")
            text_tag = container.select_one("p.comment__09f24__D0cxf span")

            reviews.append({
                "user": user_tag.get_text(strip=True) if user_tag else None,
                "rating": rating_tag["aria-label"] if rating_tag else None,
                "date": date_tag.get_text(strip=True) if date_tag else None,
                "text": text_tag.get_text(strip=True) if text_tag else None,
            })

        time.sleep(random.uniform(2, 5))

    return reviews

Umgang mit dynamischem Laden von Bewertungen. Yelp lädt Bewertungen manchmal nach dem anfänglichen Rendern der Seite über JavaScript nach. Wenn Ihr requests-basierter Scraper weniger Bewertungen zurückgibt, als Sie im Browser sehen, lädt die Seite den Bewertungsinhalt wahrscheinlich clientseitig nach. In diesem Fall haben Sie zwei Möglichkeiten: Verwenden Sie einen Headless-Browser (wie Playwright oder Puppeteer), um JavaScript zu rendern, oder suchen Sie nach den zugrunde liegenden API-Aufrufen, die die Seite tätigt.

Es gibt Hinweise darauf, dass Yelp intern einen GraphQL-Endpunkt verwendet, um Bewertungsdaten im strukturierten JSON-Format abzurufen. Falls verfügbar, könnten Sie damit das HTML-Parsing vollständig umgehen und saubere, strukturierte Bewertungsdaten erhalten. Die genaue Endpunkt-URL und die Payload-Struktur sollten jedoch anhand der Live-Website überprüft werden, da sich interne APIs ohne Vorankündigung ändern können. Der oben gezeigte HTML-Scraping-Ansatz bleibt die zuverlässigste Methode für die konsistente Extraktion von Yelp-Bewertungen.

Bewertungen sortieren. Der sort_by=date_desc in der URL stellt sicher, dass Sie die neuesten Bewertungen zuerst erhalten. Weitere Optionen sind rating_desc und rating_asc. Für Überwachungszwecke ermöglicht das nach Datum sortierte Scraping die Erkennung neuer Bewertungen durch den Vergleich mit dem Zeitstempel Ihres letzten Scrapes.

Umgang mit Anti-Bot-Schutzmaßnahmen und Ratenbeschränkungen

Yelp nimmt den Schutz seiner Daten sehr ernst. Wenn Sie Hunderte von schnellen Anfragen von einer einzigen IP-Adresse aus senden, müssen Sie mit Sperrungen rechnen. Hier ist eine mehrstufige Strategie für das zuverlässige Scraping von Yelp.

Wechseln Sie die User-Agent-Strings. Das Senden desselben User-Agent-Headers bei jeder Anfrage ist ein eindeutiges Erkennungsmerkmal. Führen Sie eine Liste realistischer Browser-User-Agent-Strings und wechseln Sie diese nach dem Zufallsprinzip. Aktuelle UA-Strings finden Sie in Quellen wie user-agents.net.

import random

USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0) AppleWebKit/605.1.15 Safari/605.1.15",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/119.0.0.0 Safari/537.36",
]

def get_headers():
    return {
        "User-Agent": random.choice(USER_AGENTS),
        "Accept-Language": "en-US,en;q=0.9",
        "Accept": "text/html,application/xhtml+xml",
    }

Fügen Sie realistische Verzögerungen hinzu. Zufällige Verzögerungen zwischen 2 und 5 Sekunden ahmen menschliche Surfgewohnheiten nach. Bei groß angelegten Abläufen sollten Sie eine längere Wartezeit (10 bis 30 Sekunden) zwischen den Seiten mit Unternehmensdetails einplanen, da es sich dabei um schwergewichtige Anfragen handelt, die in den Serverprotokollen auffallen.

Proxy-Rotation. Wenn Sie mehr als ein paar Dutzend Seiten von Yelp scrapen, ist die Rotation Ihrer IP-Adressen unerlässlich. Sie können Ihren eigenen Proxy-Pool einrichten oder einen Proxy-Rotationsdienst nutzen. Der Schlüssel liegt darin, die Anfragen auf viele IP-Adressen zu verteilen, damit keine einzelne Adresse Rate-Limits auslöst.

def make_request(url, proxies_list):
    proxy = random.choice(proxies_list)
    proxy_dict = {"http": proxy, "https": proxy}
    headers = get_headers()
    try:
        response = requests.get(url, headers=headers, proxies=proxy_dict, timeout=15)
        return response
    except requests.RequestException as e:
        print(f"Request failed via {proxy}: {e}")
        return None

Wiederholungslogik mit exponentiellem Backoff. Wenn Sie eine 429- (Ratenbegrenzung) oder 403- (blockiert) Antwort erhalten, versuchen Sie es nicht sofort erneut. Warten Sie und versuchen Sie es dann mit einer längeren Verzögerung erneut:

def fetch_with_retry(url, max_retries=3):
    for attempt in range(max_retries):
        response = requests.get(url, headers=get_headers(), timeout=15)
        if response.status_code == 200:
            return response
        wait = (2 ** attempt) + random.uniform(0, 1)
        print(f"Retrying in {wait:.1f}s (status {response.status_code})")
        time.sleep(wait)
    return None

Beachten Sie robots.txt. Zum Zeitpunkt der Erstellung dieses Artikels robots.txt das Crawlen bestimmter Pfade ein und legt Crawl-Delay-Einstellungen fest. Überprüfen Sie immer die aktuellen Anweisungen, bevor Sie einen Scraper starten. Das Ignorieren robots.txt birgt nicht nur das Risiko einer Sperrung, sondern wirft auch ethische und potenziell rechtliche Bedenken auf. Verantwortungsbewusstes Scraping bedeutet, sich an die von der Website veröffentlichten Grenzen zu halten.

Beschleunigung Ihres Scrapers mit asynchronen Anfragen

Der oben beschriebene synchrone Scraper funktioniert gut für kleine Aufgaben, aber wenn Sie Daten zu Tausenden von Yelp-Unternehmen sammeln, summiert sich das sequenzielle Warten auf jede HTTP-Antwort schnell. Mit asynchronem HTTP können Sie mehrere Anfragen gleichzeitig auslösen und so die Gesamtdauer des Scrapings drastisch reduzieren.

Hier ist ein minimales asynchrones Muster unter Verwendung von httpx:

import httpx
import asyncio

async def fetch_page(client, url):
    try:
        response = await client.get(url, timeout=15)
        return response.text if response.status_code == 200 else None
    except httpx.RequestError:
        return None

async def scrape_urls_async(urls, concurrency=5):
    semaphore = asyncio.Semaphore(concurrency)
    results = []

    async def bounded_fetch(client, url):
        async with semaphore:
            html = await fetch_page(client, url)
            results.append((url, html))
            await asyncio.sleep(random.uniform(1, 3))

    async with httpx.AsyncClient(headers=get_headers()) as client:
        tasks = [bounded_fetch(client, url) for url in urls]
        await asyncio.gather(*tasks)

    return results

The Semaphore mit concurrency=5 begrenzt die Anzahl der gleichzeitigen Anfragen auf fünf. Das ist wichtig: Wenn Sie Yelp mit 50 gleichzeitigen Verbindungen bombardieren, werden alle IP-Adressen in Ihrem Pool schnell gesperrt. Beginnen Sie mit 3 bis 5 gleichzeitigen Anfragen und erhöhen Sie die Anzahl vorsichtig, während Sie Ihre Erfolgsquote überwachen.

Jede Aufgabe beinhaltet außerdem eine zufällige Verzögerung nach Abschluss. Dies verhindert das „Thundering-Herd“-Muster, bei dem alle fünf Slots gleichzeitig frei werden und sofort fünf neue Anfragen auf einmal gesendet werden.

Asynchrones Scraping ist besonders nützlich, wenn du bereits eine Liste von URLs hast, die du besuchen möchtest (zum Beispiel URLs von Unternehmensseiten, die in der Suchergebnisphase gesammelt wurden). Du analysierst die HTML-Antworten mit demselben BeautifulSoup-Code wie zuvor, da sich die Parsing-Logik nicht ändert, nur weil das Abrufen asynchron erfolgt.

Speichern und Exportieren Ihrer Yelp-Daten

Scraping ist nur dann sinnvoll, wenn Sie die Ergebnisse in einem Format speichern, das Ihre nachgelagerten Tools verarbeiten können. Hier sind drei gängige Exportmöglichkeiten für gescrapte Yelp-Daten.

Der CSV-Export ist die einfachste Option und funktioniert mit praktisch jedem Analysetool:

def export_to_csv(data, filename="yelp_data.csv"):
    if not data:
        return
    keys = data[0].keys()
    with open(filename, "w", newline="", encoding="utf-8") as f:
        writer = csv.DictWriter(f, fieldnames=keys)
        writer.writeheader()
        writer.writerows(data)
    print(f"Exported {len(data)} records to {filename}")

Der JSON-Export bewahrt verschachtelte Strukturen (wie Öffnungszeiten oder Bewertungslisten), die in CSV unübersichtlich abgeflacht werden:

def export_to_json(data, filename="yelp_data.json"):
    with open(filename, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=2, ensure_ascii=False)
    print(f"Exported {len(data)} records to {filename}")

SQLite ist ein guter Mittelweg, wenn Sie einen abfragbaren Speicher benötigen, ohne einen Datenbankserver einrichten zu müssen:

import sqlite3

def export_to_sqlite(data, db_name="yelp.db", table="businesses"):
    conn = sqlite3.connect(db_name)
    cursor = conn.cursor()
    if data:
        cols = ", ".join(f"{k} TEXT" for k in data[0].keys())
        cursor.execute(f"CREATE TABLE IF NOT EXISTS {table} ({cols})")
        placeholders = ", ".join("?" for _ in data[0])
        for row in data:
            cursor.execute(
                f"INSERT INTO {table} VALUES ({placeholders})",
                list(row.values())
            )
    conn.commit()
    conn.close()

Bei den meisten Yelp-Scraping-Projekten sollten Sie mit JSON beginnen (es verarbeitet verschachtelte Bewertungsdaten auf natürliche Weise) und dann in CSV umwandeln, wenn Sie Daten in Tabellenkalkulationen oder Pandas DataFrames laden müssen. SQLite ist sinnvoll, wenn Sie wiederholte Scrapes durchführen und historische Daten abfragen möchten, ohne alles in den Arbeitsspeicher zu laden.

Yelp-Daten in LLM-fähige Erkenntnisse umwandeln

An dieser Stelle unterscheidet sich dieses Tutorial von allen anderen Anleitungen zum Yelp-Scraping. Sobald Sie Bewertungen gesammelt haben, können Sie diese durch ein großes Sprachmodell leiten, um Erkenntnisse zu gewinnen, deren manuelle Zusammenstellung Stunden dauern würde.

Der Arbeitsablauf umfasst drei Schritte: Bereinigen der Daten, Formatieren als strukturierte Eingabe und Aufrufen des LLM.

Schritt 1: Konvertieren Sie die Bewertungen in einen Markdown-Zusammenfassungsblock. LLMs erzielen die besten Ergebnisse, wenn die Eingabedaten klar strukturiert sind:

def reviews_to_markdown(reviews, business_name):
    lines = [f"# Reviews for {business_name}\n"]
    for r in reviews:
        lines.append(f"- **{r['rating']}** ({r['date']}): {r['text']}\n")
    return "\n".join(lines)

Schritt 2: Erstellen Sie eine Eingabeaufforderung, die nach bestimmten Ergebnissen fragt. Sagen Sie nicht einfach „Fassen Sie diese Bewertungen zusammen“. Formulieren Sie konkret, was Sie wollen:

def build_analysis_prompt(markdown_reviews):
    return (
        "Analyze the following Yelp reviews and provide:\n"
        "1. A 2-sentence overall summary\n"
        "2. Top 3 positive themes with example quotes\n"
        "3. Top 3 negative themes with example quotes\n"
        "4. An estimated sentiment score (1-10)\n\n"
        f"{markdown_reviews}"
    )

Schritt 3: Senden Sie die Eingabe an das LLM Ihrer Wahl. Hier ist ein einfaches Beispiel mit dem OpenAI-Client, aber jede LLM-API (oder ein lokales Modell) funktioniert:

from openai import OpenAI

def analyze_reviews(reviews, business_name):
    client = OpenAI()
    md = reviews_to_markdown(reviews, business_name)
    prompt = build_analysis_prompt(md)

    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.3,
    )
    return response.choices[0].message.content

Diese Pipeline wandelt rohe Yelp-Bewertungen in strukturierte Wettbewerbsinformationen um. Sie könnten sie für jeden Wettbewerber in einer Kategorie ausführen und einen Bericht erstellen, der die Stimmungslandschaft automatisch abbildet. Zur Lead-Generierung könnten Sie Unternehmen mit sinkender Stimmung als potenzielle Kunden für Ihre Dienstleistung markieren.

Die wichtigste Erkenntnis ist, dass gescrapte Yelp-Daten dramatisch an Wert gewinnen, wenn Sie eine LLM-Zusammenfassungsschicht darüberlegen. Das Scraping liefert Ihnen das Rohmaterial; das LLM verwandelt es in Entscheidungen.

Best Practices und ethische Richtlinien für das Scraping

Verantwortungsbewusstes Scraping von Yelp (oder jeder anderen Website) bedeutet nicht nur, Sperren zu vermeiden. Es geht darum, auf eine Weise zu arbeiten, die nachhaltig und vertretbar ist.

Drosseln Sie aggressiv. Nur weil Sie 100 Anfragen pro Sekunde senden können, heißt das nicht, dass Sie es tun sollten. Aggressives Scraping verschlechtert das Erlebnis für echte Nutzer. Halten Sie sich an Verzögerungen von mindestens 2 bis 5 Sekunden zwischen den Anfragen und reduzieren Sie Ihre Parallelität während der Spitzenzeiten.

Speichern Sie Antworten im Cache. Wenn Sie Ihren Parser iterieren, speichern Sie den rohen HTML-Code lokal im Cache, damit Sie beim Debuggen von Selektoren nicht wiederholt auf die Server von Yelp zugreifen. Ein einfacher dateibasierter Cache (speichern Sie jede Seite als {business_id}.html) reduziert die Anzahl Ihrer Anfragen drastisch.

Gehen Sie verantwortungsbewusst mit Daten um. Bewertungen enthalten personenbezogene Daten (Namen der Verfasser, manchmal auch Standorte). Wenn Sie diese Daten speichern, wenden Sie angemessene Zugriffskontrollen und Aufbewahrungsrichtlinien an. Wenn Sie in der EU ansässig sind oder EU-Nutzerdaten verarbeiten, gilt die DSGVO.

Veröffentlichen Sie keine gescrapten Inhalte erneut. Die Verwendung von Yelp-Daten für interne Analysen unterscheidet sich erheblich vom erneuten Posten von Bewertungen auf Ihrer eigenen Website. Ersteres ist im Allgemeinen vertretbar; Letzteres führt zu rechtlichen und ethischen Problemen.

Wichtige Erkenntnisse

  • Beginnen Sie mit den Suchergebnissen und bauen Sie darauf auf. Ein funktionierender Yelp-Scraper durchläuft drei Phasen: Suchergebnisse, Unternehmensdetails und schließlich Bewertungen. Erstellen und validieren Sie jede Phase, bevor Sie zur nächsten übergehen.
  • Die Stabilität der Selektoren ist entscheidend. Die data-testid sind zuverlässiger als generierte CSS-Klassennamen. Überprüfen Sie Selektoren immer anhand der Live-Seite und bauen Sie elegante Fallbacks ein.
  • Ratenbegrenzung ist Ihre wichtigste Maßnahme gegen Blockierungen. Zufällige Verzögerungen, Proxy-Rotation und User-Agent-Randomisierung wirken zusammen, aber die Dosierung Ihrer Anfragen ist die effektivste Taktik.
  • Das Exportformat hängt von Ihrem nachgelagerten Workflow ab. Verwenden Sie JSON für verschachtelte Bewertungsdaten, CSV für die Analyse in Tabellenkalkulationen und SQLite für wiederholte Scrapes mit abfragbarem Verlauf.
  • LLM-Pipelines verwandeln Rohdaten aus Bewertungen in verwertbare Erkenntnisse. Die Einspeisung strukturierter Bewertungsdaten in ein LLM zur Stimmungsanalyse und Themenextraktion ist ein Kraftmultiplikator, mit dem kein noch so umfangreiches manuelles Lesen mithalten kann.

FAQ

Die Rechtmäßigkeit hängt von Ihrer Rechtsordnung ab, davon, wie Sie auf die Daten zugreifen, und davon, was Sie damit tun. Gerichte unterscheiden im Allgemeinen zwischen dem Scraping öffentlich zugänglicher Daten und der Umgehung von Zugriffskontrollen. Die Nutzungsbedingungen von Yelp verbieten den automatisierten Zugriff, doch die Durchsetzbarkeit der Nutzungsbedingungen variiert je nach Rechtsordnung. Konsultieren Sie einen Rechtsbeistand für Ihren spezifischen Anwendungsfall und vermeiden Sie stets das Scraping hinter Login-Barrieren oder die Umgehung technischer Einschränkungen.

Verfügt Yelp über eine öffentliche API, die ich anstelle des Scrapings nutzen kann?

Yelp bietet die Yelp Fusion API an, die strukturierten Zugriff auf die Unternehmenssuche, Unternehmensdetails und Bewertungen ermöglicht. Die API weist jedoch erhebliche Einschränkungen auf: Die Bewertungsdaten sind auf drei Auszüge pro Unternehmen begrenzt, die Ratenbeschränkungen sind relativ streng und einige auf der Website verfügbare Felder werden über die API nicht bereitgestellt. Für eine umfassende Sammlung von Bewertungen oder bei großem Datenbedarf ist das Scraping oft die praktikable Alternative.

Wie vermeide ich, dass meine IP-Adresse beim Scraping von Yelp gesperrt wird?

Wechseln Sie die IP-Adressen mithilfe eines Proxy-Pools, randomisieren Sie User-Agent-Header und fügen Sie realistische Verzögerungen (2 bis 5 Sekunden) zwischen den Anfragen ein. Implementieren Sie einen exponentiellen Backoff bei 429- oder 403-Antworten. Halten Sie die Parallelität niedrig (3 bis 5 gleichzeitige Anfragen). Überwachen Sie Ihre Erfolgsquote und reduzieren Sie die Anzahl der Anfragen, wenn sie unter 90 % fällt. Residential-Proxys sind für Websites schwerer zu erkennen als Datencenter-Proxys.

Kann ich Yelp-Bewertungen scrapen, ohne einen Headless-Browser zu verwenden?

Ja, für die meisten Unternehmen. Yelp rendert den ersten Satz an Bewertungen im serverseitigen HTML, den Sie mit requests und BeautifulSoup analysieren können. Die Paginierung funktioniert über den start Abfrageparameter. Headless-Browser sind nur erforderlich, wenn Yelp Bewertungen für bestimmte Seiten dynamisch über JavaScript lädt, was bei der standardmäßigen Paginierung von Bewertungen seltener vorkommt.

Was ist die beste Python-Bibliothek zum Scrapen von Yelp?

Für die meisten Projekte ist die Kombination aus requests (HTTP-Abruf) und BeautifulSoup mit dem lxml Parser (HTML-Parsing) der beste Ausgangspunkt. Wenn Sie asynchrone Unterstützung für groß angelegte Datenerfassung benötigen, httpx ist eine gute Alternative zu requests. Für Seiten, die eine JavaScript-Darstellung erfordern, sind Playwright oder Selenium die ersten Wahl, auch wenn sie deutlich langsamer sind.

Fazit

Sie verfügen nun über ein komplettes Toolkit zum Scrapen von Yelp mit Python. Vom Sammeln von Suchergebnissen über das Parsen von Unternehmensdaten bis hin zum Extrahieren von Bewertungen in großem Umfang wird jeder Schritt der Pipeline durch funktionierenden Code abgedeckt. Die asynchronen Muster ermöglichen eine Skalierung, wenn das Projekt dies erfordert, und die LLM-Integration wandelt rohen Bewertungstext in strukturierte Erkenntnisse um, auf die Sie reagieren können.

Die größte Herausforderung bei jedem Yelp-Scraping-Projekt ist nicht das Parsen, sondern die Aufrechterhaltung eines zuverlässigen Zugriffs. Zwischen IP-Sperren, CAPTCHA-Herausforderungen und sich ändernden HTML-Strukturen verschlingt die Request-Ebene mehr Entwicklungszeit als die Logik zur Datenextraktion. Wenn Sie sich lieber darauf konzentrieren möchten, was Sie mit den Daten machen, anstatt gegen Anti-Bot-Systeme anzukämpfen, übernimmt unsere Scraper-API die Proxy-Rotation, CAPTCHAs und Wiederholungsversuche hinter einem einzigen Endpunkt, sodass Ihr BeautifulSoup-Code genau so bleibt, wie er ist.

Egal, für welchen Ansatz du dich entscheidest: Fange klein an, überprüfe deine Selektoren anhand von Live-Seiten und baue das Ganze schrittweise aus. Die von uns behandelten Anwendungsfälle (Stimmungsanalyse, Wettbewerbsbenchmarking, Lead-Generierung) basieren alle auf derselben Grundlage: sauberen, strukturierten Yelp-Daten, die über einen längeren Zeitraum zuverlässig gesammelt wurden.

Über den Autor
Raluca Penciuc, Full-Stack-Entwickler @ WebScrapingAPI
Raluca PenciucFull-Stack-Entwickler

Raluca Penciuc ist Full-Stack-Entwicklerin bei WebScrapingAPI. Sie entwickelt Scraper, verbessert Umgehungsstrategien und findet zuverlässige Wege, um die Erkennung auf Zielwebsites zu verringern.

Los geht’s

Sind Sie bereit, Ihre Datenerfassung zu erweitern?

Schließen Sie sich den über 2.000 Unternehmen an, die WebScrapingAPI nutzen, um Webdaten im Unternehmensmaßstab ohne zusätzlichen Infrastrukturaufwand zu extrahieren.