Airbnb ist eine der größten Kurzaufenthaltsplattformen im Web, und seine öffentlichen Angebotsseiten enthalten genau die strukturierten Felder, die für Marktforschung, Preisverfolgung und Reisevergleiche relevant sind: der Angebots-Titel, der Preis pro Nacht, die Bewertung mit Rezensionsanzahl, der Standort und die beworbenen Ausstattungsmerkmale. Für jeden, der Nachtpreise in einer Stadt untersucht oder verfolgt, wie sich ein Markt entwickelt, sind diese öffentlichen Angebotsdaten das Rohmaterial. Das manuelle Erfassen über Dutzende von Unterkünften ist langsam und fehleranfällig.

Dieser Leitfaden zeigt Ihnen, wie Sie Airbnb-Angebote mit Python zuverlässig scrapen. Sie erstellen einen kleinen, ausführbaren Scraper, der gerenderte Airbnb-Suchseiten über die Crawling API abruft, die gewünschten Angebotsfelder mit BeautifulSoup parst, die Paginierung verarbeitet und saubere JSON- und CSV-Dateien exportiert. Die gesamte Anleitung beschränkt sich auf öffentliche Angebotsdaten: keine persönlichen Informationen von Gastgebern oder Gästen, keine individuellen Bewertungen, die mit einer namentlich genannten Person verknüpft sind. Der Rechtsabschnitt am Ende ist kein Boilerplate, lesen Sie ihn also, bevor Sie dies auf reales Volumen anwenden.

Was Sie erstellen werden

Ein Python-Skript, das eine öffentliche Airbnb-Such-URL für einen Standort und Reisedaten entgegennimmt, die Angebotskarten auf jeder Ergebnisseite sammelt und einen strukturierten Datensatz pro Angebot extrahiert. Das durchgehende Beispiel sind Unterkünfte in den Vereinigten Staaten, aber derselbe Ansatz funktioniert für jede öffentliche Such-URL. Wir erfassen diese Felder:

  • Titel der auf der Karte angezeigte Angebots-Titel, z. B. "Cabin in Woodstock".
  • Preis der angezeigte Preis pro Nacht.
  • Bewertung die Gesamtgastbewertung und die daneben stehende Rezensionsanzahl.
  • Standort der aus dem Angebots-Titel geparste Ortsname.
  • Ausstattung die wichtigsten Ausstattungsmerkmale, die auf der Karte erscheinen, z. B. Pool, WLAN oder Küche.
  • Link die kanonische URL der Angebotsseite.

Jedes dieser Felder ist öffentlich und nicht personenbezogen. Der Scraper berührt weder den Namen eines Gastgebers noch ein Gästeprofil, private Nachrichten oder eine Bewertung, die einer namentlich genannten Person zugeordnet ist.

Warum eine einfache Anfrage bei Airbnb scheitert

Wenn Sie eine Airbnb-Such-URL mit einem einfachen HTTP-Client abrufen, erhalten Sie eine Antwort mit Status 200, aber kaum Angebotsdaten im Body. Zwei Dinge arbeiten gegen Sie. Erstens rendert Airbnb seine Suchergebnisse im Browser per JavaScript, sodass das ursprüngliche HTML eine dünne Hülle ist, die sich erst füllt, nachdem die Skripte der Seite ausgeführt wurden. Wenn Sie diese erste Antwort parsen, erfassen Sie ein leeres Raster statt der Angebotskarten. Zweitens erkennt Airbnb automatisierten Datenverkehr schnell: Rechenzentrum-IPs und Anfragemuster, die nicht wie ein echter Browser aussehen, werden gedrosselt, IP-geblockt oder herausgefordert, bevor sie je den gerenderten Inhalt erreichen.

Ein funktionierender Airbnb-Scraper benötigt also zwei Dinge in einer einzigen Anfrage: einen Browser, der die Seite tatsächlich rendert, und eine IP, die die Plattform als echten Besucher liest. Sie können das selbst mit einem Headless-Browser und einem Pool rotierender Wohngebiets-Proxys zusammenstellen, aber diese zu verbinden und funktionsfähig zu halten, ist der größte Teil der Arbeit. Die Crawling API vereint beides in einem einzigen Aufruf: Sie senden ihr die URL mit einem JavaScript-Token, sie rendert die Seite hinter einer vertrauenswürdigen IP und gibt fertiges HTML zum Parsen zurück.

Warum das JS-Token

Crawlbase bietet zwei Token-Typen. Das normale Token ruft statisches HTML ab; das JavaScript-Token (JS-Token) rendert die Seite zuerst in einem echten Browser. Airbnb füllt sein Suchraster clientseitig, daher benötigen Sie hier das JS-Token. Das normale Token gibt dieselbe dünne Hülle zurück, die auch ein einfacher Abruf liefern würde, und es gibt kaum Nützliches daraus zu parsen.

Voraussetzungen

Sie benötigen einige Dinge, bevor Sie Code schreiben. Keines davon nimmt viel Zeit in Anspruch.

Grundlegendes Python. Sie sollten in der Lage sein, ein Python-Skript zu schreiben und auszuführen sowie Pakete mit pip zu installieren. Falls Sie neu beim Parsen sind, ist der BeautifulSoup-Leitfaden eine gute Ergänzung zu diesem Tutorial.

Python 3.8 oder höher. Überprüfen Sie Ihre Version mit python --version. Falls Sie es nicht haben, installieren Sie es von python.org oder über eine Distribution wie Anaconda, und stellen Sie sicher, dass Python in Ihrem PATH ist.

Ein Crawlbase-Konto und ein JS-Token. Registrieren Sie sich, öffnen Sie Ihr Dashboard und kopieren Sie Ihr JavaScript-Token (JS-Token) von der Konto-Dokumentationsseite. Crawlbase bietet bis zu 20.000 kostenlose Anfragen zum Start, was für diese Anleitung mehr als ausreichend ist, und Sie zahlen nur für erfolgreiche Anfragen. Behandeln Sie das Token wie ein Passwort: Es authentifiziert Ihre Anfragen, also halten Sie es aus der Versionskontrolle heraus.

Projekt einrichten

Erstellen Sie eine virtuelle Umgebung, damit Projektabhängigkeiten isoliert bleiben, und installieren Sie dann die Bibliotheken, die der Scraper benötigt.

bash
python --version

python -m venv airbnb_env
source airbnb_env/bin/activate

pip install crawlbase beautifulsoup4

Unter Windows aktivieren Sie die Umgebung mit airbnb_env\Scripts\activate anstelle der source-Zeile. Zwei Abhängigkeiten erledigen die Arbeit: crawlbase ist der offizielle Client für die Crawling API, und beautifulsoup4 parst das zurückgegebene HTML, sodass Sie einzelne Felder per CSS-Selektor herausziehen können. Sowohl json als auch csv werden mit der Standardbibliothek geliefert, sodass für den Export-Schritt nichts weiter zu installieren ist.

Schritt 1: Eine gerenderte Airbnb-Suchseite abrufen

Beginnen Sie damit, eine fertige Seite zu erhalten. Importieren Sie die CrawlingAPI-Klasse, initialisieren Sie sie mit Ihrem JS-Token und fordern Sie eine Airbnb-Such-URL an. Airbnb lädt Ergebnisse asynchron, also übergeben Sie ajax_wait und page_wait, um auf den dynamischen Inhalt zu warten, bevor die Seite erfasst wird. Das Überprüfen des Crawlbase-cb_status (legacy pc_status) vor dem Parsen hält Fehler sichtbar statt still.

python
from crawlbase import CrawlingAPI

api = CrawlingAPI({"token": "YOUR_CRAWLBASE_TOKEN"})

OPTIONS = {
    "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/122.0",
    "ajax_wait": "true",
    "page_wait": 5000,
}

def crawl(page_url):
    response = api.get(page_url, OPTIONS)
    if response["headers"]["cb_status"] == "200":
        return response["body"].decode("utf-8")
    print(f"Request failed: {response['headers']['cb_status']}")
    return None

if __name__ == "__main__":
    search_url = "https://www.airbnb.com/s/United-States/homes?checkin=2026-07-10&checkout=2026-07-12&adults=2"
    html = crawl(search_url)
    print(html[:500] if html else "No HTML returned")

Die beiden Warte-Optionen sind wichtig für ein clientseitig gerendertes Ziel wie Airbnb. ajax_wait weist die API an, zu warten, bis asynchrone Inhalte fertig geladen sind, und page_wait wartet nach dem Laden eine festgelegte Anzahl von Millisekunden, damit spät gerenderte Karten erscheinen, bevor die Seite erfasst wird. Fünf Sekunden sind ein vernünftiger Startpunkt; erhöhen Sie den Wert, wenn die Ergebnisse dünn zurückkommen. Die Such-URL enthält Standort, Ein- und Abreisedaten sowie die Anzahl der Erwachsenen, genau wie Airbnbs eigene Suche. Führen Sie das Skript mit python airbnb_scraper.py aus und Sie sollten echtes Airbnb-Such-Markup sehen, nicht die Hülle, die ein einfacher Abruf zurückgibt. Das bestätigt, dass das Rendering funktioniert, bevor Sie einen einzigen Selektor schreiben.

Crawlbase Airbnb Scraper

Airbnb benötigt eine gerenderte Seite hinter einer vertrauenswürdigen IP in einem einzigen Aufruf, was genau das ist, was die oben genannten Optionen ajax_wait und page_wait einrichten. Die Crawling API nimmt ein JS-Token, führt die Seite in einem echten Browser aus, rotiert serverseitig durch Wohngebiets-IPs und gibt Ihnen fertiges HTML, sodass Sie keinen eigenen Headless-Browser und keinen Proxy-Pool betreiben müssen. Richten Sie es auf eine öffentliche Suchseite im kostenlosen Tarif und zahlen Sie nur für erfolgreiche Anfragen.

Schritt 2: Die Angebotskarten inspizieren und die Selektoren finden

Mit einer fertigen Seite in der Hand ist der nächste Schritt herauszufinden, wo jedes Feld liegt. Öffnen Sie dieselbe Such-URL in Ihrem Browser, klicken Sie mit der rechten Maustaste auf eine Angebotskarte und wählen Sie "Untersuchen", um die Entwicklertools zu öffnen. Airbnb umschließt jedes Ergebnis in einem Element innerhalb seines Website-Inhaltsbereichs, und Titel, Bewertung und Preis befinden sich jeweils an vorhersehbaren Stellen innerhalb dieser Karte.

Aus dem Legacy-Markup ordnen sich der Angebotscontainer und seine inneren Felder diesen Selektoren zu. Sie sind eine Startvorlage: Airbnbs generierte Klassennamen rotieren, also überprüfen Sie eine Live-Seite erneut, wenn ein Feld leer zurückkommt.

  • Angebotscontainer: div#site-content div[itemprop="itemListElement"]
  • Titel: div[data-testid="listing-card-title"]
  • Bewertung und Rezensionen: span.r1dxllyb innerhalb der Karte
  • Preis pro Nacht: div._i5duul span.a8jt5op
  • Link: das href am Anker der Karte, verbunden mit dem Airbnb-Host

Schritt 3: Die Angebotsfelder parsen

Laden Sie das gerenderte HTML in BeautifulSoup, iterieren Sie über jeden Angebotscontainer und ziehen Sie die Felder mit den oben genannten Selektoren heraus. Jede Abfrage ist abgesichert, sodass ein fehlendes Feld None zurückgibt, anstatt den Durchlauf zum Absturz zu bringen. Der Titel dient auch als Quelle für den Standort: Airbnb schreibt seine Kartentitel als "Typ in Ort", sodass der Text nach "in" der Standort ist.

python
from urllib.parse import urljoin
from bs4 import BeautifulSoup

CARD = 'div#site-content div[itemprop="itemListElement"]'

def text_of(node, selector):
    el = node.select_one(selector)
    return el.get_text(strip=True) if el else None

def location_from_title(title):
    if title and " in " in title:
        return title.split(" in ", 1)[1]
    return None

def amenities_of(node):
    spans = node.select('div[data-testid="listing-card-subtitle"] span')
    items = [s.get_text(strip=True) for s in spans]
    return [a for a in items if a]

def parse_card(node):
    title = text_of(node, 'div[data-testid="listing-card-title"]')
    anchor = node.select_one("a")
    href = anchor["href"] if anchor and anchor.get("href") else None
    return {
        "title": title,
        "price": text_of(node, 'div._i5duul span.a8jt5op'),
        "rating": text_of(node, 'span.r1dxllyb'),
        "location": location_from_title(title),
        "amenities": amenities_of(node),
        "link": urljoin("https://www.airbnb.com", href) if href else None,
    }

def scrape_page(html):
    soup = BeautifulSoup(html, "html.parser")
    return [parse_card(node) for node in soup.select(CARD)]

Der Helfer text_of fragt ein Element ab und gibt seinen bereinigten Text zurück, oder None, wenn das Element fehlt, sodass eine Karte, die ein Feld weglässt, die Schleife nicht unterbricht. Der Bewertungsselektor erfasst die kombinierte Bewertung und Rezensionsanzahl, die Airbnb zusammen rendert, z. B. "4.99 (85)". location_from_title liest den Ort aus dem Kartentitel, und amenities_of sammelt die kurzen Beschreibungen, die Airbnb im Kartenuntertitel anzeigt. Das href des Ankers ist relativ, daher wandelt urljoin es in eine vollständige Angebots-URL um. Beachten Sie, was fehlt: Hier wird kein Gastgebername, kein Gastgeberprofil und kein Bewertungstext eines Gastes gelesen. Die Karte zeigt nur öffentliche Angebotsattribute, und das ist alles, was der Parser sammelt.

Selektoren verschieben sich

Airbnbs generierte Klassennamen wie r1dxllyb und a8jt5op ändern sich ohne Vorankündigung. Behandeln Sie die Selektoren hier als Startvorlage, nicht als Vertrag. Wenn ein Feld leer zurückkommt, überprüfen Sie die Live-Karte in den Entwicklertools Ihres Browsers und aktualisieren Sie den Selektor. Regelmäßige Selektor-Wartung ist bei jedem Produktions-Scraper normal und kein Zeichen für einen Fehler.

Schritt 4: Paginierung über Suchseiten verwalten

Eine Suchseite ist nur ein Ausschnitt des Ergebnissatzes. Airbnb paginiert mit einem items_offset-Abfrageparameter, der den Offset um die Seitengröße (18 Karten pro Seite) voranschreitet, um durch Ergebnisse zu navigieren. Lesen Sie den Offset für die nächste Seite aus der Paginiernav aus, wenn sie vorhanden ist, oder schrittweise den Offset selbst bis zu einer Obergrenze, damit ein großer Markt nicht entläuft. Ein kleiner Retry-Wrapper um den Abruf verhindert, dass eine einzelne langsame Seite den Durchlauf beendet.

python
import time

PAGE_SIZE = 18

def fetch_html(page_url, max_retries=2):
    for attempt in range(max_retries + 1):
        html = crawl(page_url)
        if html:
            return html
        if attempt < max_retries:
            print(f"Retrying ({attempt + 1}/{max_retries})...")
            time.sleep(1)
    print(f"Unable to fetch {page_url}")
    return None

def collect_all_listings(base_url, max_pages):
    records = []
    for page in range(max_pages):
        offset = page * PAGE_SIZE
        sep = "&" if "?" in base_url else "?"
        page_url = f"{base_url}{sep}items_offset={offset}"
        html = fetch_html(page_url)
        if not html:
            break
        page_records = scrape_page(html)
        if not page_records:
            break
        records.extend(page_records)
        time.sleep(2)
    return records

fetch_html versucht einen fehlgeschlagenen Abruf bis zu zweimal mit einer kurzen Pause erneut, gibt das HTML bei Erfolg zurück und None, sobald es aufgibt. collect_all_listings geht jede Seite durch, indem es items_offset voranschreitet, begrenzt das Crawling auf Ihre max_pages-Obergrenze und stoppt frühzeitig, wenn eine Seite keine Karten zurückgibt (das natürliche Ende der Ergebnisse). Das time.sleep(2) zwischen den Seiten drosselt den Durchlauf, sodass Sie die Website nicht überlasten.

Schritt 5: Das vollständige Skript zusammenstellen

Verbinden Sie nun die Teile zu einem ausführbaren Skript: Angebote über mehrere Seiten sammeln und die Datensätze dann in JSON und CSV exportieren.

python
import csv
import json
import time
from urllib.parse import urljoin
from crawlbase import CrawlingAPI
from bs4 import BeautifulSoup

api = CrawlingAPI({"token": "YOUR_CRAWLBASE_TOKEN"})

OPTIONS = {
    "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/122.0",
    "ajax_wait": "true",
    "page_wait": 5000,
}

CARD = 'div#site-content div[itemprop="itemListElement"]'
PAGE_SIZE = 18

def crawl(page_url):
    response = api.get(page_url, OPTIONS)
    if response["headers"]["cb_status"] == "200":
        return response["body"].decode("utf-8")
    print(f"Request failed: {response['headers']['cb_status']}")
    return None

def fetch_html(page_url, max_retries=2):
    for attempt in range(max_retries + 1):
        html = crawl(page_url)
        if html:
            return html
        if attempt < max_retries:
            time.sleep(1)
    return None

def text_of(node, selector):
    el = node.select_one(selector)
    return el.get_text(strip=True) if el else None

def location_from_title(title):
    if title and " in " in title:
        return title.split(" in ", 1)[1]
    return None

def amenities_of(node):
    spans = node.select('div[data-testid="listing-card-subtitle"] span')
    items = [s.get_text(strip=True) for s in spans]
    return [a for a in items if a]

def parse_card(node):
    title = text_of(node, 'div[data-testid="listing-card-title"]')
    anchor = node.select_one("a")
    href = anchor["href"] if anchor and anchor.get("href") else None
    return {
        "title": title,
        "price": text_of(node, 'div._i5duul span.a8jt5op'),
        "rating": text_of(node, 'span.r1dxllyb'),
        "location": location_from_title(title),
        "amenities": amenities_of(node),
        "link": urljoin("https://www.airbnb.com", href) if href else None,
    }

def scrape_page(html):
    soup = BeautifulSoup(html, "html.parser")
    return [parse_card(node) for node in soup.select(CARD)]

def collect_all_listings(base_url, max_pages):
    records = []
    for page in range(max_pages):
        offset = page * PAGE_SIZE
        sep = "&" if "?" in base_url else "?"
        html = fetch_html(f"{base_url}{sep}items_offset={offset}")
        if not html:
            break
        page_records = scrape_page(html)
        if not page_records:
            break
        records.extend(page_records)
        time.sleep(2)
    return records

def save_outputs(records):
    with open("airbnb_listings.json", "w") as f:
        json.dump(records, f, indent=2)
    if not records:
        return
    with open("airbnb_listings.csv", "w", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=records[0].keys())
        writer.writeheader()
        for r in records:
            row = {**r, "amenities": ", ".join(r["amenities"])}
            writer.writerow(row)

def main():
    search_url = "https://www.airbnb.com/s/United-States/homes?checkin=2026-07-10&checkout=2026-07-12&adults=2"
    records = collect_all_listings(search_url, max_pages=2)
    save_outputs(records)
    print(f"Saved {len(records)} listings")

if __name__ == "__main__":
    main()

Das Skript sammelt Angebote über bis zu zwei Suchseiten, parst jede Karte in einen Datensatz und drosselt die Schleife mit einem Zwei-Sekunden-Sleep. save_outputs schreibt sowohl eine JSON-Datei als auch eine CSV; für die CSV flacht es die Ausstattungsliste in einen kommaseparierten String um, damit die Spalte lesbar bleibt. Passen Sie max_pages und die Such-URL an Ihren Zielstandort und Ihre Daten an.

Wie die Ausgabe aussieht

Führen Sie das vollständige Skript mit python airbnb_scraper.py aus und Sie erhalten einen sauberen strukturierten Datensatz pro Angebot, bereit für Analysen, eine Datenbank oder eine Tabellenkalkulation. Titel, Bewertungen und Preise unten spiegeln die Form wider, die Airbnb auf seinen Karten rendert.

json
[
  {
    "title": "Cabin in Woodstock",
    "price": "$70 per night",
    "rating": "4.9 (41)",
    "location": "Woodstock",
    "amenities": ["Wifi", "Kitchen", "Free parking"],
    "link": "https://www.airbnb.com/rooms/12345678"
  },
  {
    "title": "Farm stay in Kalispell",
    "price": "$199 per night",
    "rating": "5.0 (161)",
    "location": "Kalispell",
    "amenities": ["Wifi", "Pool", "Kitchen"],
    "link": "https://www.airbnb.com/rooms/23456789"
  }
]

Die passende CSV enthält dieselben Spalten, eine Zeile pro Angebot, und kann direkt in pandas oder eine beliebige Tabellenkalkulation zum Filtern nach Preisklasse, Bewertung oder Standort geladen werden. Wenn Ihr Ziel speziell die Preisbeobachtung ist, geht der begleitende Leitfaden zum Airbnb-Preisscraping mit Python tiefer auf das Preisfeld ein, und Preisintelligenz mit Web-Scraping zeigt, was Sie mit den Zahlen tun können, sobald Sie sie haben.

Dauerhaft unblockiert bleiben

Selbst mit gehandhabtem Rendering beobachtet Airbnb Datenverkehr mit Scraper-ähnlichem Muster. Ein paar Gewohnheiten halten einen längeren Durchlauf gesund und gelten für jedes schwierige kommerzielle Ziel.

  • Drosseln Sie Ihre Anfragen. Suchseiten in einer engen Schleife zu hammern, ist der schnellste Weg, gedrosselt oder herausgefordert zu werden. Die oben genannten Zwei-Sekunden-Sleeps sind der Mindestwert, kein Maximum; erweitern Sie sie für größere Jobs und variieren Sie Ihre Ziele, statt einen einzelnen Pfad mit voller Geschwindigkeit zu crawlen.
  • Setzen Sie auf Rotation. Ein Pool von Wohngebiets-IPs verteilt Anfragen über viele echte Nutzeradressen, sodass keine einzelne Adresse ein Ratenlimit auslöst. Die Crawling API übernimmt das für Sie; wenn Sie Ihren eigenen Stack aufbauen, ist das der Teil, den Sie richtig machen müssen.
  • Lesen Sie die Statuscodes. Ein Durchlauf, der beginnt, Nicht-200-cb_status-Werte zurückzugeben, signalisiert Ihnen, dass die aktuelle Rate oder IP-Stufe nicht mehr ausreicht. Behandeln Sie das als Signal zum Drosseln, nicht als Rauschen zum Ignorieren.

Für größere Crawlings reiht der asynchrone Crawler Anfragen in die Warteschlange ein und liefert Ergebnisse an einen Webhook, was für das Abrufen vieler Suchseiten ohne offene Verbindungen geeignet ist. Das umfassendere Vorgehen finden Sie unter Websites scrapen ohne blockiert zu werden. Derselbe zweischichtige Ansatz überträgt sich auf andere Angebotsportale, wie z. B. Apartments.com scrapen.

Ob das Scrapen von Airbnb erlaubt ist, hängt von Airbnbs Nutzungsbedingungen, Ihrer Gerichtsbarkeit und dem ab, was Sie mit den Daten machen. Airbnbs Nutzungsbedingungen schränken automatisierten Zugriff, Scraping und die Erfassung von Inhalten der Plattform ein, sodass Scraping unabhängig davon, wie sorgfältig Ihr Tooling ist, gegen diese Bedingungen verstoßen kann. Keiner der hier gezeigten Code-Schnipsel ändert das; er macht nur den technischen Teil funktionsfähig. Lesen Sie Airbnbs Nutzungsbedingungen und seine robots.txt, respektieren Sie die dort implizierten Ratenlimits und behandeln Sie beides als Grenze für das, was Sie sammeln. Halten Sie Ihr Anfragevolumen niedrig genug, dass Sie Airbnbs Server nicht belasten.

Die wichtigere Grenze ist der Datenschutz. Airbnb-Angebote sind von Nutzern eingestellte Inhalte, was bedeutet, dass eine Seite Informationen über echte Menschen enthalten kann: Gastgeber und Gäste. Dieser Leitfaden beschränkt sich bewusst auf öffentliche, nicht personenbezogene Angebotsfelder, nämlich Titel, Preis pro Nacht, Bewertung, Rezensionsanzahl, Standort, Ausstattung und der Angebotslink, weil das die Linie ist, die die Arbeit vertretbar hält. Sammeln Sie keine Gastgeber- oder Gästenamen, Profilfotos, Kontaktdaten oder andere personenbezogene Daten, und scrapen Sie keine individuellen Bewertungen, die einem namentlich genannten Gast zugeordnet sind, oder stellen Sie Profile von Gastgebern zusammen. Das sind personenbezogene Daten, und wo sie betroffen sind, gelten Datenschutzgesetze wie die DSGVO in der EU und der CCPA in Kalifornien mit ihren eigenen Anforderungen und Strafen. Die öffentliche Verfügbarkeit eines Feldes macht es nicht frei zum Erfassen, wenn es eine Person identifiziert.

Für alles jenseits einer kleinen, öffentlichen, nicht personenbezogenen Stichprobe ist der richtige Weg ein offizieller Kanal und kein clevererer Scraper. Airbnb betreibt Partner- und API-Programme für erlaubte Integrationen, und das ist der korrekte Weg für kommerzielle oder massenhafte Nutzung. Im Zweifelsfall über einen konkreten Anwendungsfall: Holen Sie sich rechtlichen Rat, bevor Sie ein Produkt auf den Daten aufbauen. Die obige technische Anleitung ist eine Möglichkeit, die Mechanik auf öffentlichen Daten zu erlernen, keine Lizenz zur Massenerfassung oder zum Zugriff auf individuelle Daten.

Zusammenfassung

Wichtigste Erkenntnisse

  • Airbnb wird clientseitig gerendert. Eine einfache Anfrage gibt eine dünne Hülle mit einem leeren Raster zurück, also müssen Sie die Seite rendern, bevor Sie sie parsen.
  • Sie benötigen Rendering und eine vertrauenswürdige IP zusammen. Die Crawling API mit einem JS-Token macht beides in einem einzigen Aufruf; ajax_wait und page_wait steuern, wie lange auf Inhalte gewartet wird.
  • Parsen Sie die Karte, nicht die Person. Iterieren Sie über die itemListElement-Container und lesen Sie Titel, Preis, Bewertung mit Rezensionsanzahl, Standort, Ausstattung und Link, allesamt öffentliche und nicht personenbezogene Felder.
  • Paginieren und exportieren. Erhöhen Sie Airbnbs items_offset-Parameter bis zu einer Obergrenze, drosseln Sie den Durchlauf mit kurzen Sleeps und schreiben Sie die Datensätze in JSON und CSV.
  • Bleiben Sie bei öffentlichen Daten. Respektieren Sie Airbnbs ToS und robots.txt, sammeln Sie niemals persönliche Daten von Gastgebern oder Gästen oder namentlich genannte Bewertungen, beachten Sie, dass DSGVO und CCPA für personenbezogene Daten gelten, und nutzen Sie Airbnbs offizielle oder Partner-API für die Produktion.

Häufig gestellte Fragen

Warum gibt eine einfache Anfrage ein leeres Airbnb-Raster zurück?

Weil Airbnb seine Suchergebnisse clientseitig mit JavaScript lädt. Das initiale HTML ist eine Hülle, die sich erst füllt, nachdem die Skripte der Seite in einem Browser ausgeführt wurden. Eine einfache HTTP-Anfrage gibt Status 200 ohne Angebotskarten zurück. Um den vollständigen Satz zu erhalten, müssen Sie die Seite zuerst rendern, was das JS-Token der Crawling API für Sie übernimmt.

Benötige ich das normale Token oder das JS-Token für Airbnb?

Das JS-Token. Das normale Token ruft statisches HTML ab, das bei Airbnb dieselbe dünne Hülle wie ein einfacher Abruf zurückgibt. Das JS-Token rendert die Seite in einem echten Browser, bevor es das HTML zurückgibt, sodass die Angebotskarten und ihre Felder vorhanden sind, wenn BeautifulSoup sie parst. Credits unterscheiden sich für normale und JavaScript-Anfragen, also überprüfen Sie Ihr Dashboard.

Welche Felder kann ich von einem Airbnb-Angebot scrapen?

Öffentliche, nicht personenbezogene Angebotsfelder: den Angebots-Titel, den Preis pro Nacht, die Bewertung und Rezensionsanzahl, den Standort, die wichtigsten Ausstattungsmerkmale und den Angebotslink. Bleiben Sie bei Daten, die für jeden Besucher ohne Konto sichtbar sind, und sammeln Sie niemals Gastgeber- oder Gästenamen, Profile, Kontaktdaten oder individuelle Bewertungen, die einer namentlich genannten Person zugeordnet sind. Das sind personenbezogene Daten und fallen außerhalb des öffentlichen Angebotsbereichs, den dieser Leitfaden behandelt.

Meine Selektoren geben None zurück. Was hat sich geändert?

Höchstwahrscheinlich Airbnbs Markup. Seine generierten Klassennamen (r1dxllyb für die Bewertung, a8jt5op für den Preis und die Test-ID listing-card-title) ändern sich ohne Vorankündigung, sodass Selektoren, die letzten Monat funktionierten, kaputt gehen können. Überprüfen Sie eine Live-Karte in den Entwicklertools Ihres Browsers und aktualisieren Sie die Selektoren. Regelmäßige Selektor-Wartung ist bei jedem Produktions-Scraper normal.

Wie verwalte ich die Paginierung über die Angebote eines Standorts?

Airbnb steuert Ergebnisse mit einem items_offset-Abfrageparameter, der um die Seitengröße von 18 Karten voranschreitet. Die Funktion collect_all_listings oben erhöht den Offset seitenweise, begrenzt das Crawling auf eine max_pages-Obergrenze und stoppt, sobald eine Seite keine Karten zurückgibt. Lassen Sie einen kurzen Sleep zwischen den Seiten, damit der Durchlauf höflich bleibt.

Kann ich gescrapte Airbnb-Daten kommerziell nutzen?

Behandeln Sie das als Rechtsfrage, nicht als technische. Airbnbs Nutzungsbedingungen schränken Scraping und Weiterverwendung ein, und Angebote können personenbezogene Daten enthalten, die durch Gesetze wie die DSGVO und den CCPA abgedeckt sind, sodass kommerzielle oder massenhafte Nutzung generell einer Genehmigung bedarf. Prüfen Sie die Bedingungen, nutzen Sie Airbnbs offizielle oder Partner-API für die Produktion und holen Sie sich rechtlichen Rat, bevor Sie ein Produkt auf den Daten aufbauen.

Jetzt loslegen

Crawlen Sie jede Website im großen Maßstab, ohne gegen die Infrastruktur zu kämpfen.

Crawlbase übernimmt Proxys, Fingerprints und CAPTCHAs, damit Ihr Team Datenpipelines ausliefert, statt Crawl-Infrastruktur zu pflegen. 1.000 Anfragen kostenlos, keine Karte erforderlich.

Self-Service · Kein Verkaufsgespräch erforderlich · Enterprise-Crawl-Volumen verfügbar