Zurück zum Blog
Anleitungen
Raluca PenciucLast updated on May 8, 202613 min read

Web Scraping Booking.com: Hotels, Preise und Bewertungen (2026 Guide)

Web Scraping Booking.com: Hotels, Preise und Bewertungen (2026 Guide)
Kurzfassung: Dieser Leitfaden führt Sie Schritt für Schritt durch das Web-Scraping von Booking.com in Python: Abrufen von Suchergebnissen, Hotelseiten, Übernachtungspreisen und Gästebewertungen. Sie erhalten zwei sich ergänzende Methoden: einen Selenium-Wire-Workflow für mit JavaScript gerenderte Seiten und einen schnelleren Weg, der den internen /dml/graphql Endpunkt aufruft, sowie ein Anti-Block-Playbook, Währungsumrechnung und eine Umgehungslösung für die Begrenzung der Seitenanzeige auf etwa 1.000 Ergebnisse.

Booking.com ist die Art von Datensatz, auf die Teams aus der Reise- und Gastgewerbebranche immer wieder zurückgreifen: aktuelle Übernachtungspreise, Positionierung der Konkurrenz, Angebot nach Stadtviertel, Gästebewertungen nach Unterkunft. Der Haken ist, dass nichts davon über eine offene API für die breite Öffentlichkeit zugänglich ist. Wenn Sie also programmgesteuert darauf zugreifen wollen, müssen Sie letztendlich selbst eine Form des Webscrapings bei Booking.com durchführen. Dieses Tutorial zeigt zwei praktische Python-Ansätze und verknüpft sie mit den produktionstechnischen Herausforderungen, die den meisten Anwendern in der zweiten Woche Probleme bereiten.

Zum Zeitpunkt der Erstellung dieses Artikels ist Booking.com eine der größten Unterkunftsplattformen im Internet mit Millionen buchbarer Unterkünfte, darunter Hotels, Resorts und Kurzzeitaufenthalte. (Wir halten uns bei den genauen Zahlen an Schätzungen; die öffentlichen Zahlen des Unternehmens schwanken.) Die Plattform ist stark JavaScript-basiert und verfügt über echte Anti-Bot-Maßnahmen, sodass naive requests.get Skripte scheitern oft, bevor sie überhaupt nützlich werden.

Sie werden sehen, wie man einen Selenium-basierten Scraper für Suchergebnisse ausführt, wie man dieselben Daten aus dem internen GraphQL-Endpunkt rückentwickelt, wie man Hotel-Detailseiten, Preise und Bewertungen abruft und wie man mit Sitemaps und Abfragepartitionierung die Ergebnisbegrenzung umgeht. Der Code ist in Python 3.10+ geschrieben und setzt voraus, dass Sie mit DevTools und CSS-Selektoren vertraut sind.

Warum sich das Web-Scraping von Booking.com lohnt

Es gibt eine Handvoll Anwendungsfälle, in denen sich das Web-Scraping von Booking.com fast sofort auszahlt. Preisinformations-Teams vergleichen Übernachtungspreise bei konkurrierenden Hotels in Echtzeit. Revenue Manager verfolgen Verfügbarkeiten und Rabattmuster, um den richtigen Zeitpunkt für ihre eigenen Werbeaktionen zu bestimmen. Marktforschungs- und Reiseanalyse-Teams nutzen das Volumen an Bewertungen, Bewertungen und die Ausstattung, um ein Reiseziel zu bewerten. Und jeder, der eine Metasuchmaschine oder einen KI-Reisevermittler entwickelt, benötigt strukturierte Objektdaten, die die öffentliche Website nur innerhalb von JavaScript rendert.

In diesem Leitfaden werden wir fünf konkrete Entitätstypen extrahieren: Suchergebnislisten (Hotelkarten auf einer Suchergebnisseite), Hotel-Detailseiten (Beschreibung, Adresse, Ausstattung, Geolokalisierung), Preise pro Nacht und Verfügbarkeit, Gästebewertungen sowie ein auf der Sitemap basierendes Hotelinventar für die Massenabfrage. Jeder Typ hat seine eigenen Besonderheiten, und erst durch deren Kombination erhält man einen echten Datensatz statt nur eines einzelnen Screenshots einer SERP.

Auswahl eines Scraping-Ansatzes: Browser-Automatisierung vs. versteckte API

Es gibt zwei sinnvolle Möglichkeiten, Web-Scraping auf Booking.com in jedem Umfang durchzuführen, und diese ergänzen sich eher, als dass sie miteinander konkurrieren.

Selenium mit Selenium Wire steuert eine echte Chrome-Instanz an, führt das JavaScript der Seite aus und ermöglicht es Ihnen, das gerenderte DOM auszulesen. Dies ist die reibungsloseste Option, wenn Sie die versteckten Anfragen der Seite noch nicht kennen, und sie toleriert Layoutabweichungen gut, da Sie dasselbe DOM abfragen, das auch ein Nutzer sieht. Der Preis dafür ist Geschwindigkeit und Ressourcenverbrauch: Jede Seite ist ein vollständiger Browser-Tab. Für kuratierte Listen mit einigen Tausend Hotels ist das in Ordnung. Für die kontinuierliche Überwachung wird es jedoch teuer.

Aufruf des internen /dml/graphql Endpunkt mit httpx umgeht den Browser vollständig. Das eigene Frontend von Booking.com ruft Suchergebnisse von diesem Endpunkt ab. Sobald Sie also die Anforderungsform nachbilden, erhalten Sie dasselbe JSON wie die Website – zehn- bis fünfzigmal schneller als mit Selenium und mit minimalem Speicherbedarf. Der Nachteil ist die Anfälligkeit: Payloads und erforderliche Header ändern sich, und Sie müssen diese synchron halten.

Eine solide Vorgehensweise: Erstellen Sie einen Prototyp mit Selenium, legen Sie die GraphQL-Anfrage fest, sobald Sie die Daten verstanden haben, und nutzen Sie den API-Pfad für die Produktion.

Einrichten Ihrer Python-Umgebung

Verwenden Sie Python 3.10 oder neuer in einer neuen virtualenv, damit die Abhängigkeiten isoliert bleiben:

mkdir booking_scraper && cd booking_scraper
python -m venv .venv && source .venv/bin/activate
pip install selenium selenium-wire webdriver-manager httpx parsel
touch app.py

selenium-wire ist ein direkter Ersatz für selenium das die zugrunde liegenden Netzwerkanfragen offenlegt, die wir für die Paginierungssynchronisation benötigen. webdriver-manager lädt automatisch die passende chromedriver Binärdatei automatisch herunter, sodass Sie die Treiberversionen nicht auf verschiedenen Rechnern verwalten müssen. httpx bietet uns einen HTTP/2-fähigen Client für Methode 2, und parsel bietet CSS- und XPath-Selektoren im Scrapy-Stil zum Parsen von Hotel-HTML. Unser Schritt-für-Schritt-Selenium-Tutorial ist eine nützliche Einführung, falls du Selenium noch nie zum Scraping verwendet hast.)

Methode 1: Scraping von Suchergebnissen mit Selenium und Selenium Wire

Dies ist der benutzerfreundlichste Einstieg in das Web-Scraping von Booking.com: Öffnen Sie eine Such-URL in einer echten Chrome-Sitzung, lassen Sie JavaScript die Objektkarten rendern und durchlaufen Sie das DOM. Wir verwenden Selenium Wire anstelle von Vanilla Selenium, da die Suchseite Ergebnisse über XHR-/Fetch-Aufrufe im Hintergrund lädt. Mit Selenium Wire können wir diese einzelnen Anfragen überprüfen und warten, bis eine bestimmte Antwort tatsächlich zurückkommt, was für die Paginierung ohne Race-Conditions wichtig ist.

Laden der Suchseite und Isolieren der Unterkunftskarten

Füge immer explizite An- und Abreisedaten in die URL ein. Ohne diese greift Booking.com auf die Standardverfügbarkeit zurück, und deine Preisspalte stimmt nicht mit dem überein, was ein Nutzer in einem echten Buchungsfenster sehen würde.

from seleniumwire import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
url = ('https://www.booking.com/searchresults.html'
       '?ss=London&checkin=2026-05-10&checkout=2026-05-12&group_adults=2')
driver.get(url)

cards = driver.find_elements(By.CSS_SELECTOR, "div[data-testid='property-card']")
print(f'Found {len(cards)} property cards on page 1')

Booking.com verwendet data-testid Attribute auf seinen Ergebniskarten, was sie als Zielobjekte stabiler macht als automatisch generierte Klassennamen.

Extrahieren von Name, Adresse, Bewertung, Anzahl der Bewertungen, Preis und Bild

Jede Unterkunftskarte enthält dieselben wenigen data-testid Hooks, sodass der Parser pro Karte meist nur ein kleines Wörterbuch von Selektoren ist. CSS-Selektoren sind hier in der Regel die richtige Wahl (prägnant und schnell), aber XPath ist gut geeignet, wenn du eine Durchquerung von über- oder gleichrangigen Elementen benötigst. Sieh dir unseren Leitfaden „XPath vs. CSS-Selektoren“ an, wenn du dich entscheiden musst.

def parse_card(card):
    def text(sel):
        nodes = card.find_elements(By.CSS_SELECTOR, sel)
        return nodes[0].text.strip() if nodes else None

    def attr(sel, name):
        nodes = card.find_elements(By.CSS_SELECTOR, sel)
        return nodes[0].get_attribute(name) if nodes else None

    score_block = text("div[data-testid='review-score']") or ''
    score_lines = [s.strip() for s in score_block.split('\n') if s.strip()]
    score = score_lines[0] if score_lines else None
    review_count = next((l for l in score_lines if 'review' in l.lower()), None)

    return {
        'name':         text("div[data-testid='title']"),
        'url':          attr("a[data-testid='title-link']", 'href'),
        'address':      text("span[data-testid='address']"),
        'score':        score,
        'review_count': review_count,
        'price':        text("span[data-testid='price-and-discounted-price']"),
        'image':        attr("img[data-testid='image']", 'src'),
    }

listings = [parse_card(c) for c in cards]

Zwei Dinge sind bei den Preisen zu beachten. Erstens: Der review-score Block auf Booking.com fasst die numerische Bewertung und den Text zur Anzahl der Bewertungen in einem Element zusammen, daher teilen wir ihn in Zeilen auf und extrahieren sie separat. Zweitens enthält der Preis, den Sie aus einer Suchkarte scrapen, fast immer keine Steuern und Gebühren; der Gesamtpreis erscheint erst, wenn Sie im Buchungsablauf weiter voranschreiten. Behandeln Sie ihn als Richtpreis, nicht als Endpreis, und dokumentieren Sie dies im weiteren Verlauf.

Durchklicken der Paginierung ohne Race Conditions

Jeder Klick auf die Schaltfläche „Nächste Seite“ löst einen POST-Request aus /dml/graphql und wartet auf die Rückgabe von JSON. Wenn Sie klicken und sofort das DOM auslesen, lesen Sie die vorherige Seite. Selenium Wire behebt dies, indem es Ihnen ermöglicht, auf die tatsächliche Antwort zu warten.

from selenium.webdriver.common.by import By

def total_pages(driver):
    nums = driver.find_elements(By.CSS_SELECTOR, "div[data-testid='pagination'] li")
    return max((int(n.text) for n in nums if n.text.isdigit()), default=1)

pages = total_pages(driver)
all_listings = [parse_card(c) for c in cards]

for page in range(2, pages + 1):
    del driver.requests  # clear so the next wait does not match an old response
    next_btn = driver.find_element(
        By.CSS_SELECTOR, "button[aria-label='Next page']")
    next_btn.click()
    driver.wait_for_request(r'/dml/graphql', timeout=10)
    cards = driver.find_elements(
        By.CSS_SELECTOR, "div[data-testid='property-card']")
    all_listings.extend(parse_card(c) for c in cards)

del driver.requests ist die wichtige Zeile. Ohne sie wait_for_request wird der GraphQL-Aufruf der vorherigen Seite fälschlicherweise abgeglichen, und Sie springen weiter, bevor die neuen Daten eintreffen. Beziehen Sie die Gesamtseitenanzahl aus dem Paginierungselement, anstatt sie fest zu codieren; bei stark frequentierten Abfragen kann die Paginierung zwanzig Seiten umfassen, bei ruhigen nur zwei.

Methode 2: Den GraphQL-Such-Endpunkt von Booking.com direkt aufrufen

Sobald Selenium dir gezeigt hat, dass die Suchseite von /dml/graphql, ist es schneller, diesen Endpunkt selbst aufzurufen und den Browser zu umgehen. Hier wird das Web-Scraping von Booking.com wirklich skalierbar.

Der Erkundungsprozess ist derselbe, den Sie für jede [versteckte JavaScript-API] verwenden würden: Öffnen Sie DevTools (F12), wechsle zum Reiter „Netzwerk“, filtere nach „Fetch/XHR“, löse dann eine echte Suche aus und klicke auf Seite zwei. Du siehst einen POST an /dml/graphql , der einen JSON-Body mit einem operationName, einem variables Objekt (mit Reiseziel, Daten, Gästeanzahl und einem offset) sowie ein query oder extensions Feld, das den Abfrage-Hash festlegt. Klicken Sie mit der rechten Maustaste auf die Anfrage und wählen Sie „Als cURL kopieren“ – das ist Ihr Ausgangspunkt.

Überprüfe die genauen Feldnamen vor der Veröffentlichung noch einmal anhand deiner eigenen DevTools-Erfassung; Booking.com benennt GraphQL-Operationen regelmäßig um, und die sicherste Referenz ist das, was das Frontend heute sendet.

import httpx

ENDPOINT = 'https://www.booking.com/dml/graphql'
HEADERS = {
    'content-type':    'application/json',
    'origin':          'https://www.booking.com',
    'referer':         'https://www.booking.com/searchresults.html',
    'user-agent':      'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                       'AppleWebKit/537.36 (KHTML, like Gecko) '
                       'Chrome/124.0 Safari/537.36',
    'accept-language': 'en-US,en;q=0.9',
}

def search_page(client, payload, offset):
    body = {**payload}
    body['variables']['input']['pagination'] = {'offset': offset, 'rowsPerPage': 25}
    r = client.post(ENDPOINT, json=body, headers=HEADERS, timeout=30)
    r.raise_for_status()
    return r.json()

def search_all(payload, max_results=1000):
    results = []
    with httpx.Client(http2=True) as client:
        for offset in range(0, max_results, 25):
            page = search_page(client, payload, offset)
            hits = (page.get('data', {})
                        .get('searchQueries', {})
                        .get('search', {})
                        .get('results', []))
            if not hits:
                break
            results.extend(hits)
    return results

Zwei Details, an denen viele scheitern. Der Endpunkt gibt pro Aufruf 25 Ergebnisse zurück, gesteuert durch eine Offset-Variable, die du in Schritten von 25 Ergebnissen erhöhst. Und die Anfrage muss so aussehen, als käme sie von der Website selbst: origin und referer auf booking.com, content-type: application/jsonund auf accept-language , das Ihrer IP-Region entspricht. Entfernen Sie diese Header, und Sie erhalten innerhalb weniger Anfragen einen generischen 400-Fehler oder eine Soft-Sperre. Verwenden Sie HTTP/2 (httpx tut dies, wenn Sie http2=True), da der Edge von Booking.com offenbar Clients identifiziert, die weiterhin nur HTTP/1.1 verhandeln.

Einzelne Hotelseiten nach Beschreibung, Adresse und Ausstattung scrapen

Suchergebniskarten sind nur ein Teil des Web-Scrapings bei Booking.com; sie liefern dir einen Namen und einen Preis, aber nicht die detaillierten Hotelinformationen, die Reiseteams tatsächlich benötigen. Dazu musst du die Hotel-URL direkt scrapen. Hotelseiten werden meist serverseitig gerendert, daher reicht ein einfacher GET-Befehl parsel aus, ein Browser ist nicht erforderlich.

import httpx
from parsel import Selector

def scrape_hotel(url):
    html = httpx.get(url, headers=HEADERS, http2=True, follow_redirects=True).text
    sel = Selector(text=html)
    map_link = sel.css("a[data-atlas-latlng]::attr(data-atlas-latlng)").get('')
    lat, lng = (map_link.split(',') + [None, None])[:2]
    return {
        'name':        sel.css('h2.pp-header__title::text').get(default='').strip(),
        'description': ' '.join(sel.css("div[data-testid='property-description'] *::text").getall()).strip(),
        'address':     sel.css("span[data-testid='address']::text").get(default='').strip(),
        'lat':         lat,
        'lng':         lng,
        'amenities':   [a.strip() for a in sel.css("div[data-testid='facility-list-most-popular'] li::text").getall() if a.strip()],
    }

Längen- und Breitengrad sind in der Regel in einem data-atlas-latlng Attribut des Kartenlinks eingebettet, was zuverlässiger ist, als sie aus Inline-Skripten zu extrahieren. Ausstattungsmerkmale sind in Funktionsblöcken gruppiert; durchlaufen Sie die Gruppen, wenn Sie sie kategorisiert statt flach dargestellt haben möchten.

Abrufen von Übernachtungspreisen und Verfügbarkeit

Die Preise pro Nacht sind nicht im Hotel-HTML enthalten; sie liegen hinter einer separaten GraphQL-Abfrage, die eine kalenderförmige Antwort zurückgibt. Erfassen Sie die Anfrage auf die gleiche Weise wie den Suchaufruf: Öffnen Sie die Hotelseite in DevTools, ändern Sie die Daten und achten Sie auf den POST-Request für Preise/Verfügbarkeit an /dml/graphql. Der Body enthält die Hotel-Identifikatoren (numerisch hotel_id, Ländercode und Währung) sowie einen Datumsbereich.

Hotelseiten betten zudem ein CSRF-ähnliches Token in den HTML-Code ein, das die Preisanfrage im Hauptteil oder in einem Header erwartet. Extrahieren Sie es einmal pro Hotel aus der Seite und verwenden Sie es dann für jeden Preisaufruf wieder.

def scrape_pricing(client, hotel_id, csrf, checkin, checkout, currency='EUR'):
    payload = {
        'operationName': 'AvailabilityCalendar',  # verify in DevTools
        'variables': {
            'input': {
                'hotelId': hotel_id,
                'checkIn': checkin,
                'checkOut': checkout,
                'currency': currency,
            }
        },
        'extensions': {'csrf': csrf},
    }
    r = client.post(ENDPOINT, json=payload, headers=HEADERS, timeout=30)
    r.raise_for_status()
    return r.json()

Abrufen von Gästebewertungen über den versteckten Bewertungs-Endpunkt

Gästebewertungen werden über einen separaten XHR-Aufruf geladen, wenn Sie auf einer Hotelseite auf die Registerkarte „Bewertungen“ klicken. Öffnen Sie DevTools, wechseln Sie zu „Fetch/XHR“, klicken Sie auf die Registerkarte und kopieren Sie die Anfrage. Sie blättert durch eine skip (oder offset) Ganzzahl in Stapeln von etwa 25 und gibt Bewertungstext, Punktzahl, Sprache, Land des Bewerters und Datum zurück.

Sobald Sie einen funktionierenden Aufruf haben, können Sie parallel arbeiten, indem Sie Batches in einem httpx.AsyncClient:

import asyncio, httpx

async def fetch_reviews(client, hotel_id, skip):
    r = await client.post(ENDPOINT, json=review_payload(hotel_id, skip), headers=HEADERS)
    return r.json()

async def all_reviews(hotel_id, total):
    async with httpx.AsyncClient(http2=True) as c:
        tasks = [fetch_reviews(c, hotel_id, s) for s in range(0, total, 25)]
        return await asyncio.gather(*tasks)

Halten Sie die Parallelität pro Hotel im einstelligen Bereich; Bewertungen unterliegen einer strengen Ratenbegrenzung.

Hotels über Sitemaps und die Standort-Autocomplete-API finden

Für das Web-Scraping des Booking.com-Bestands in großen Mengen – anstatt des Scrapings mit jeweils einer Abfrage – beginnen Sie bei https://www.booking.com/robots.txt. Booking.com veröffentlicht dort seine Sitemap: Einträge dort, einschließlich Sitemap-Indizes für Hotels, Sehenswürdigkeiten und Flughäfen. Jeder Sitemap-Index verweist auf Unter-Sitemaps, die auf 50.000 URLs begrenzt sind (gemäß dem Sitemap-Protokoll), weshalb der Hotelindex auf viele Dateien aufgeteilt ist. Wenn Sie den Index durchgehen, erhalten Sie Dutzende Millionen von Hotel-URLs, einschließlich Duplikaten, die Sie anhand des URL-Slugs oder einer geparsten Hotel-ID deduplizieren können. Unser Leitfaden zum Scraping von Sitemaps enthält hierfür ein wiederverwendbares Muster.

Für gezielte Suchanfragen wandelt der eigene Endpunkt für die Standort-Autovervollständigung von Booking.com eine Stadt- oder Stadtteilzeichenfolge in die Zielkennungen um, die der GraphQL-Suchaufruf erwartet – das ist besser, als sie manuell fest zu programmieren.

Blockierungen vermeiden: Header, Proxys, Ratenbegrenzung und Captchas

Erfolgreiches Web-Scraping bei Booking.com in beliebigem Umfang hängt davon ab, wie ein normaler Browser zu wirken und sich zurückzuziehen, wenn die Website dies verlangt. Seit 2026 scheint der Anti-Bot-Stack von Booking.com sowohl TLS- als auch HTTP/2-Verhalten zu erfassen, daher sind die Grundlagen unverzichtbar: ein HTTP/2-fähiger Client (httpx mit http2=True), ein realistischer Header-Satz einschließlich accept-language und sec-ch-ua-*sowie eine stabile user-agent , der einer aktuellen Chrome-Version entspricht. (Überprüfen Sie die HTTP/2-Empfindlichkeit regelmäßig; diese ändert sich.)

Verwenden Sie Proxys von Privathaushalten oder Internetdienstanbietern anstelle von Rechenzentrums-IP-Bereichen; Rechenzentrums-IPs, die auf Booking.com zugreifen, lösen bereits nach wenigen Dutzend Anfragen Captchas aus. Halten Sie die Parallelität konservativ (5 bis 10 pro IP), fügen Sie Jitter hinzu und reduzieren Sie die Anzahl der Anfragen bei 429 und 403. Das Residential-Proxy-Netzwerk und die Scraper-API von WebScrapingAPI übernehmen sowohl die Rotation als auch die Wiederholungsversuche und die TLS-Fingerabdruck-Aspekte, falls Sie diese Infrastruktur nicht neu aufbauen möchten. Anti-Detect-Browser sind ein letzter Ausweg für die schwierigsten Seiten.

Umgang mit Währung, Sprache und der Begrenzung auf 1.000 Ergebnisse pro Seite

Booking.com leitet die angezeigte Währung aus der Geolokalisierung Ihrer Ausgangs-IP ab, sodass ein in den USA ansässiger Scraper standardmäßig USD und ein in der EU ansässiger Scraper standardmäßig EUR sieht. Um eine konsistente Währung zu gewährleisten, leiten Sie den Datenverkehr über einen länderspezifischen Proxy oder übergeben Sie bei jeder Anfrage einen selected_currency Abfrageparameter bei jeder Anfrage übergeben. (Testen Sie dieses Verhalten regelmäßig erneut; der Parametername und die Logik zur IP-Ermittlung sind Dinge, die sich still und leise ändern können.)

Die Plattform begrenzt zudem jede einzelne Suche auf etwa 1.000 Ergebnisse. Um das Angebot in einer stark frequentierten Stadt zu erfassen, teilen Sie die Abfrage auf: Scrapen Sie London nach Stadtvierteln (Shoreditch, Camden, Kensington), dann nach Sternebewertung, dann nach Preisklasse und führen Sie die Ergebnisse anhand der Hotel-ID zusammen.

Zusammenfassung und nächste Schritte

Für Produktionsläufe integrieren Sie diesen Code in Scrapy und lassen Sie das Tool Wiederholungsversuche, Persistenz und verteilte Läufe übernehmen. Speichern Sie die normalisierte Ausgabe in Postgres oder einem spaltenorientierten Speicher, erstellen Sie täglich Snapshots und stellen Sie sicher, dass Ihre Scraper die robots.txt und den Nutzungsbedingungen von Booking.com.

Wichtige Erkenntnisse

  • Das Web-Scraping von Booking.com funktioniert am besten mit zwei Methoden in Kombination: Selenium Wire für das Prototyping und die DOM-Stabilität sowie der interne /dml/graphql Endpunkt über httpx für Produktionsgeschwindigkeit.
  • Rufen Sie den vollständigen Satz an Entitäten ab (Suchergebnisse, Hotel-Detailseiten, Übernachtungspreise und Gästebewertungen) und nicht nur die Such-SERP, da der Datensatz sonst für Preisanalysen zu dünn ist.
  • Verwenden Sie data-testid Selektoren und wait_for_request on /dml/graphql , um den Suchseiten-Scraper widerstandsfähig gegen Layoutverschiebungen und Race-Conditions bei der Paginierung zu machen.
  • Planen Sie von vornherein die Einschränkungen der Plattform ein: Residential-Proxys, HTTP/2-Header, IP-basierte Währungsauswahl und die Begrenzung der Paginierung auf etwa 1.000 Ergebnisse, die eine Aufteilung der Abfragen erzwingt.
  • Verwenden Sie Sitemaps unter /robots.txt für die massenhafte Erfassung von Hotel-URLs und die Standort-Autocomplete-API zur Auflösung von Zielkennungen.

FAQ

In den meisten Rechtsordnungen wird das Scraping öffentlich sichtbarer Hotelauflistungen, Preise und aggregierter Bewertungen im Allgemeinen als zulässig angesehen, sofern es in angemessener Häufigkeit und ohne Umgehung der Authentifizierung erfolgt. Allerdings spielen die Nutzungsbedingungen, die EU-Datenbankrichtlinie und die DSGVO (für alle Informationen, die Rückschlüsse auf die Identität von Bewertern zulassen) eine Rolle. Lassen Sie Ihren konkreten Anwendungsfall vor der kommerziellen Nutzung von einem Rechtsbeistand prüfen und vermeiden Sie die Speicherung personenbezogener Daten.

Wie kann ich die Währung steuern, die Booking.com an meinen Scraper zurückgibt?

Zwei zuverlässige Möglichkeiten: Leiten Sie Anfragen über einen Proxy in dem Land weiter, dessen Währung Sie verwenden möchten (Booking.com leitet die Währung aus der Ausgangs-IP ab), oder übergeben Sie bei jeder Anfrage einen selected_currency=EUR-artigen Abfrageparameter an jede Anfrage, um die abgeleitete Standardeinstellung zu überschreiben. Kombinieren Sie beide Methoden zur Konsistenz, da die Überschreibung gelegentlich ignoriert wird, wenn die IP-Adresse und der Parameter bei Hotels, deren Preise in einer festen lokalen Währung angegeben sind, miteinander in Konflikt stehen.

Wie kann ich mehr als 1.000 Ergebnisse für eine stark frequentierte Stadt wie London oder New York extrahieren?

Teilen Sie die Abfrage auf. Booking.com begrenzt jede einzelne Suche auf etwa 1.000 Ergebnisse. Die Lösung besteht daher darin, die Stadt in kleinere Teilmengen zu unterteilen, die jeweils unter diese Obergrenze fallen: nach Stadtviertel, dann nach Sternebewertung und bei Bedarf nach Preisklasse. Führen Sie die resultierenden Hotel-IDs zusammen und entfernen Sie Duplikate. Für eine vollständige Bestandsaufnahme greifen Sie auf die Durchsuche des Hotel-Sitemap-Index zurück, anstatt die Suchoberfläche zu nutzen.

Sollte ich Selenium verwenden oder den GraphQL-Endpunkt von Booking.com direkt aufrufen?

Verwenden Sie Selenium für die Erkundung und kleinere Aufgaben; nutzen Sie den GraphQL-Endpunkt für den großen Maßstab. Selenium ist fehlertoleranter bei Änderungen am Frontend, da Sie das gerenderte DOM abfragen. GraphQL ist pro Anfrage weitaus schneller und kostengünstiger, aber Sie müssen die Anfrage-Payloads und -Header mit der Live-Website synchron halten. Ein gängiges Vorgehen ist es, beides zu pflegen und bei einem Ausfall der API auf den Browser umzuschalten.

Warum unterscheiden sich die Preise, die mein Scraper anzeigt, von denen, die ich im Browser sehe?

Fast immer liegt einer von drei Gründen vor: Ihre An- und Abreisedaten sind nicht in der URL festgehalten, Ihre Ausgangs-IP hat die Währung geändert oder einen regionalen Rabatt angewendet, oder der Preis auf der Suchkarte enthält keine Steuern und Gebühren, die der Browser erst im nächsten Schritt anzeigt. Halten Sie die Daten fest, legen Sie die Währung fest und kennzeichnen Sie die gescrapten Preise eindeutig als Übernachtungspreise vor Steuern.

Alles zusammen

Das Web-Scraping von Booking.com ist ein lösbares Problem, sobald man aufhört, es wie eine einzelne Seite zu behandeln, und anfängt, es wie ein Ökosystem von Endpunkten zu betrachten. Selenium Wire bietet Ihnen einen benutzerfreundlichen Einstieg für Suchergebnisse und Paginierung, der interne /dml/graphql Endpunkt bietet die für die kontinuierliche Überwachung erforderliche Geschwindigkeit, und spezielle Aufrufe für Hotel-Detailseiten, Übernachtungspreise und Bewertungen runden den Datensatz ab. Ergänzen Sie dies um Sitemap-Erkennung, Abfragepartitionierung und explizite Währungssteuerung, und Sie erhalten einen Scraper, der weit über das einfache Beispiel mit einer einzigen Abfrage hinausgeht.

Die Aspekte, die die meisten Teams unterschätzen, sind die infrastrukturellen: TLS- und HTTP/2-Fingerprinting, die Qualität privater Proxys, Wiederholungs- und Backoff-Logik sowie die Geduld, Selektoren und GraphQL-Payloads im Einklang zu halten, während sich die Website weiterentwickelt.

Wenn Sie diese Anti-Block-Schicht lieber nicht selbst verwalten möchten, bietet unser Team bei WebScrapingAPI eine Scraper-API an, die rohes HTML über rotierende private IP-Adressen zurückgibt, wobei CAPTCHAs und die TLS-Verarbeitung für Sie verwaltet werden, sowie eine Browser-API für die mehrstufigen Interaktionen, die Selenium in diesem Leitfaden abwickelt. Fügen Sie eine der beiden vor den obigen Code ein, und Sie können sich auf das Parsing und das Datenmodell konzentrieren – also genau den Teil, der Ihr Produkt tatsächlich von anderen abhebt.

Ü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.