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

Nutzen Sie das Potenzial Ihrer Daten: So gewinnen Sie wertvolle Informationen aus Booking.com

Nutzen Sie das Potenzial Ihrer Daten: So gewinnen Sie wertvolle Informationen aus Booking.com

Als führendes Online-Reisebüro ist Booking.com eine Fundgrube für wertvolle Daten zu Hotels und Ferienwohnungen auf der ganzen Welt. Von Gästebewertungen über Preise bis hin zur Verfügbarkeit – die auf Booking verfügbaren Informationen können für eine Vielzahl von Zwecken unglaublich nützlich sein.

Ob Sie nun ein Unternehmer sind, der die Konkurrenz einschätzt, oder ein Datenwissenschaftler, der Trends in der Hotellerie analysiert – Web Scraping ist ein leistungsstarkes Werkzeug, mit dem Sie die benötigten Daten von Booking-Seiten sammeln können.

Am Ende dieses Tutorials werden Sie ein solides Verständnis dafür haben, wie Sie Booking.com mithilfe der beliebten Node.js-Automatisierungsbibliothek Puppeteer scrapen können. Wir konzentrieren uns auf die Extraktion von Angebotsdetails aus Madeira, Portugal, aber die in diesem Tutorial behandelten Techniken und Konzepte lassen sich auch auf andere Websites und Datenpunkte anwenden.

Voraussetzungen

Falls Sie Ihre Node.js-Umgebung noch nicht eingerichtet haben, besuchen Sie einfach die offizielle Website, um die neueste Version für Ihr Betriebssystem herunterzuladen. Erstellen Sie anschließend ein neues Verzeichnis und führen Sie den folgenden Befehl aus, um Ihr Projekt zu initialisieren:

npm init -y

Wir werden TypeScript zum Schreiben des Codes verwenden. Diese Erweiterung von JavaScript bietet optionale statische Typisierung und weitere Funktionen. Sie ist nützlich für größere Projekte und kann es erleichtern, Fehler frühzeitig zu erkennen. Sie müssen sie zu den Entwicklungsabhängigkeiten des Projekts hinzufügen und ihre Konfigurationsdatei initialisieren:

npm install typescript -save-dev npx tsc -init

Stellen Sie einfach sicher, dass in der neu generierten Datei tsconfig.json die Eigenschaft „outDir“ auf „dist“ gesetzt ist, da wir den TypeScript-Code vom kompilierten Code trennen möchten.

Zuletzt fügt der folgende Befehl Puppeteer zu den Projektabhängigkeiten hinzu:

npm install puppeteer

Puppeteer ist eine Node.js-Bibliothek, die eine High-Level-API zur Steuerung eines headless Chrome-Browsers bereitstellt, der für Web-Scraping und Automatisierungsaufgaben genutzt werden kann

Datenquelle

Für dieses Tutorial haben wir uns entschieden, die auf den Madeira-Inseln in Portugal verfügbaren Unterkünfte zu scrapen: https://www.booking.com/searchresults.en-us.html?ss=Madeira+Islands&checkin=2023-01-13&checkout=2023-01-15. Es ist wichtig, das An- und Abreisedatum zur URL hinzuzufügen, damit alle Informationen zu den Unterkünften verfügbar sind.

Diese Anleitung behandelt die Extraktion der folgenden Unterkunftsdaten:

  • den Namen
  • die URL
  • die physische Adresse
  • den Preis
  • die Bewertung und die Anzahl der Bewertungen
  • das Vorschaubild

Sie sind im folgenden Screenshot hervorgehoben:

Wenn Sie für jedes dieser Elemente die Entwicklertools öffnen, können Sie die CSS-Selektoren erkennen, die wir zum Auffinden der HTML-Elemente verwenden werden. Wenn Sie noch nicht so vertraut mit der Funktionsweise von CSS-Selektoren sind, können Sie gerne diesen Leitfaden für Anfänger zu Rate ziehen.

Auswerten der Daten

Da alle Einträge die gleiche Struktur und die gleichen Daten aufweisen, können wir alle Informationen für die gesamte Immobilienliste in unserem Algorithmus extrahieren. Nach Ausführung des Skripts können wir alle Ergebnisse durchlaufen und zu einer einzigen Liste zusammenfassen.

Bei einem ersten Blick auf das HTML-Dokument ist dir vielleicht aufgefallen, dass die Booking-Website ziemlich komplex ist und die Klassennamen meist zufällig generiert werden.

Zu unserem Glück stützt sich die Website nicht ausschließlich auf Klassennamen, und wir können den Wert eines bestimmten Attributs als Extraktionskriterium verwenden. Im obigen Screenshot haben wir hervorgehoben, wie leicht zugänglich die Miniaturansicht, der Name und die URL einer Unterkunft sind.

import puppeteer from 'puppeteer';

async function scrapeBookingData(booking_url: string): Promise<void> {

    // Launch Puppeteer

    const browser = await puppeteer.launch({

        headless: false,

    	  args: ['--start-maximized'],

    	  defaultViewport: null

    })

    const page = await browser.newPage()

    // Navigate to the channel URL

    await page.goto(booking_url)

    // Extract listings name

    const listings_name = await page.evaluate(() => {

        const names = document.querySelectorAll('div[data-testid="title"]')

    	  const names_array = Array.from(names)

    	  return names ? names_array.map(n => n.textContent) : []

    })

    console.log(listings_name)

    // Extract listings location

    const listings_location = await page.evaluate(() => {

        const locations = document.querySelectorAll('a[data-testid="title-link"]')

    	  const locations_array = Array.from(locations)

    	  return locations ? locations_array.map(l => l.getAttribute('href')) : []

    })

    console.log(listings_location)

    // Extract listings thumbnail

    const listings_thumbnail = await page.evaluate(() => {

        const thumbnails = document.querySelectorAll('[data-testid="image"]')

    	  const thumbnails_array = Array.from(thumbnails)

    	  return thumbnails ? thumbnails_array.map(t => t.getAttribute('src')) : []

    })

    console.log(listings_thumbnail)

    await browser.close()

}

scrapeBookingData("https://www.booking.com/searchresults.en-us.html?ss=Madeira+Islands&checkin=2023-01-13&checkout=2023-01-15")

Wir haben Puppeteer verwendet, um eine Browserinstanz zu öffnen, eine neue Seite zu erstellen, zu unserer Ziel-URL zu navigieren, die genannten Daten zu extrahieren und anschließend den Browser zu schließen. Zu Zwecken der visuellen Fehlerbehebung verwende ich den Nicht-Headless-Modus des Browsers.

Wie oben erläutert, waren die Daten dank des Attributs „data-testid“, das dem HTML-Element einen eindeutigen Wert zugewiesen hat, leicht zugänglich. Führen Sie den folgenden Befehl aus, um das Skript auszuführen:

npx tsc && node dist/index.js

Dein Terminal sollte drei Listeneinträge gleicher Größe anzeigen, die die Namen, die URLs und die Miniaturansichten aller Objekte auf der aktuellen Seite darstellen.

Für den nächsten Abschnitt des HTML-Dokuments haben wir die Adresse, die Bewertung und die Anzahl der Bewertungen für eine Immobilie hervorgehoben.

// Extract listings address

const listings_address = await page.evaluate(() => {

    const addresses = document.querySelectorAll('[data-testid="address"]')

    const addresses_array = Array.from(addresses)

    return addresses ? addresses_array.map(a => a.textContent) : []

})

console.log(listings_address)

// Extract listings rating and review count

const listings_rating = await page.evaluate(() => {

    const ratings = document.querySelectorAll('[data-testid="review-score"]')

    const ratings_array = Array.from(ratings)

    return ratings ? ratings_array.map(r => r.textContent) : []

})

console.log(listings_rating)

Wie zuvor haben wir das Attribut „data-testid“ verwendet. Wenn Sie das Skript erneut ausführen, sollten Ihnen zwei weitere Listen angezeigt werden, genau wie die vorherigen.

Und schließlich haben wir im letzten Abschnitt den Preis der Immobilie extrahiert. Der Code unterscheidet sich nicht von dem, was wir zuvor gemacht haben:

// Extract listings price

const listings_price = await page.evaluate(() => {

    const prices = document.querySelectorAll('[data-testid="price-and-discounted-price"]')

    const prices_array = Array.from(prices)

    return prices ? prices_array.map(p => p.textContent) : []

})

console.log(listings_price)

Um die extrahierten Daten für die weitere Verarbeitung zu vereinfachen, fassen wir die resultierenden Listen zu einer einzigen zusammen.

// Group the lists

const listings = []

for (let i = 0; i < listings_name.length; i++) {

    listings.push({

        name: listings_name[i],

        url: listings_location[i],

        address: listings_address[i],

        price: listings_price[i],

        ratings: listings_rating[i],

        thumbnails: listings_thumbnail[i]

    })

}

console.log(listings)

Das Endergebnis sollte nun wie folgt aussehen:

[

  {

    name: 'Pestana Churchill Bay',

    url: 'https://www.booking.com/hotel/pt/pestana-churchill-bay.html?aid=304142&label=gen173nr-1FCAQoggJCFnNlYXJjaF9tYWRlaXJhIGlzbGFuZHNIMVgEaMABiAEBmAExuAEXyAEM2AEB6AEB-AEDiAIBqAIDuAK9luydBsACAdICJGViMWY2MmRjLWJhZmEtNGZhZC04MDAyLWQ4MmU3YjU5MTMwZtgCBeACAQ&ucfs=1&arphpl=1&checkin=2023-01-13&checkout=2023-01-15&group_adults=2&req_adults=2&no_rooms=1&group_children=0&req_children=0&hpos=1&hapos=1&sr_order=popularity&srpvid=42cc81de452009eb&srepoch=1673202494&all_sr_blocks=477957801_262227867_0_1_0&highlighted_blocks=477957801_262227867_0_1_0&matching_block_id=477957801_262227867_0_1_0&sr_pri_blocks=477957801_262227867_0_1_0__18480&tpi_r=2&from_sustainable_property_sr=1&from=searchresults#hotelTmpl',

    address: 'Câmara de Lobos',

    price: '911 lei',

    ratings: '9.0Wonderful 727 reviews',

    thumbnails: 'https://cf.bstatic.com/xdata/images/hotel/square200/202313893.webp?k=824dc3908c4bd3e80790ce011f763f10fd4064dcb5708607f020f2e7c92d130e&o=&s=1'

  },

  {

    name: 'Hotel Madeira',

    url: 'https://www.booking.com/hotel/pt/madeira-funchal.html?aid=304142&label=gen173nr-1FCAQoggJCFnNlYXJjaF9tYWRlaXJhIGlzbGFuZHNIMVgEaMABiAEBmAExuAEXyAEM2AEB6AEB-AEDiAIBqAIDuAK9luydBsACAdICJGViMWY2MmRjLWJhZmEtNGZhZC04MDAyLWQ4MmU3YjU5MTMwZtgCBeACAQ&ucfs=1&arphpl=1&checkin=2023-01-13&checkout=2023-01-15&group_adults=2&req_adults=2&no_rooms=1&group_children=0&req_children=0&hpos=2&hapos=2&sr_order=popularity&srpvid=42cc81de452009eb&srepoch=1673202494&all_sr_blocks=57095605_262941681_2_1_0&highlighted_blocks=57095605_262941681_2_1_0&matching_block_id=57095605_262941681_2_1_0&sr_pri_blocks=57095605_262941681_2_1_0__21200&tpi_r=2&from_sustainable_property_sr=1&from=searchresults#hotelTmpl',

    address: 'Se, Funchal',

    price: '1,045 lei',

    ratings: '8.3Very Good 647 reviews',

    thumbnails: 'https://cf.bstatic.com/xdata/images/hotel/square200/364430623.webp?k=8c1e510da2aad0fc9ff5731c3874e05b1c4cceec01a07ef7e9db944799771724&o=&s=1'

  },

  {

    name: 'Les Suites at The Cliff Bay - PortoBay',

    url: 'https://www.booking.com/hotel/pt/les-suites-at-the-cliff-bay.html?aid=304142&label=gen173nr-1FCAQoggJCFnNlYXJjaF9tYWRlaXJhIGlzbGFuZHNIMVgEaMABiAEBmAExuAEXyAEM2AEB6AEB-AEDiAIBqAIDuAK9luydBsACAdICJGViMWY2MmRjLWJhZmEtNGZhZC04MDAyLWQ4MmU3YjU5MTMwZtgCBeACAQ&ucfs=1&arphpl=1&checkin=2023-01-13&checkout=2023-01-15&group_adults=2&req_adults=2&no_rooms=1&group_children=0&req_children=0&hpos=3&hapos=3&sr_order=popularity&srpvid=42cc81de452009eb&srepoch=1673202494&all_sr_blocks=395012401_247460894_2_1_0&highlighted_blocks=395012401_247460894_2_1_0&matching_block_id=395012401_247460894_2_1_0&sr_pri_blocks=395012401_247460894_2_1_0__100000&tpi_r=2&from_sustainable_property_sr=1&from=searchresults#hotelTmpl',

    address: 'Sao Martinho, Funchal',

    price: '4,928 lei',

    ratings: '9.5Exceptional 119 reviews',

    thumbnails: 'https://cf.bstatic.com/xdata/images/hotel/square200/270120962.webp?k=68ded1031f5082597c48eb25c833ea7fcedc2ec2bc5d555adfcac98b232f9745&o=&s=1'

  }

]

Alternativen

Auch wenn das Tutorial bis zu diesem Punkt recht einfach erschien, müssen wir die üblichen Fallstricke beim Web-Scraping erwähnen, insbesondere wenn Sie Ihr Projekt skalieren möchten.

Heutzutage setzen Websites verschiedene Techniken zur Bot-Erkennung ein und sammeln Browserdaten, um automatisierten Datenverkehr zu verhindern oder zu blockieren. Booking.com bildet hier keine Ausnahme. Mithilfe des PerimeterX-Schutzes führt die Website Überprüfungen Ihrer IP-Adresse durch und sammelt verschiedene Informationen:

  • Eigenschaften des Navigator-Objekts (deviceMemory, Sprachen, Plattform, userAgent, Webdriver usw.)
  • Auflistung von Schriftarten und Plugins
  • Überprüfung der Bildschirmabmessungen
  • und vieles mehr.

Eine Lösung für diese Herausforderungen ist die Verwendung einer Scraping-API, die eine einfache und zuverlässige Möglichkeit bietet, auf Daten von Websites wie Booking.com zuzugreifen, ohne dass Sie einen eigenen Scraper erstellen und warten müssen.

WebScrapingAPI ist ein solches Produkt, das Proxy-Rotation nutzt, um CAPTCHAs zu umgehen, und Browserdaten randomisiert, um einen echten Nutzer nachzuahmen. Um loszulegen, registrieren Sie sich einfach für ein Konto und holen Sie sich Ihren API-Schlüssel aus dem Dashboard. Dieser Schlüssel wird zur Authentifizierung Ihrer Anfragen verwendet.

Um die API schnell mit dem bereits vorhandenen Node.js-Projekt zu testen, können wir das entsprechende SDK nutzen. Führen Sie einfach den folgenden Befehl aus:

npm install webscrapingapi

Jetzt müssen Sie nur noch die bisherigen CSS-Selektoren an die API anpassen. Die Funktion für Extraktionsregeln ermöglicht es Ihnen, Daten mit minimalen Änderungen zu parsen, was sie zu einem leistungsstarken Werkzeug in Ihrem Web-Scraping-Toolkit macht.

import webScrapingApiClient from 'webscrapingapi';

const client = new webScrapingApiClient("YOUR_API_KEY");

async function exampleUsage() {

    const api_params = {

        'render_js': 1,

    	  'proxy_type': 'datacenter',

    	  'timeout': 60000,

    	  'extract_rules': JSON.stringify({

            names: {

                selector: 'div[data-testid="title"]',

                output: 'text',

                all: '1'

        	},

        	locations: {

                selector: 'a[data-testid="title-link"]',

                output: '@href',

                all: '1'

        	},

        	addresses: {

                selector: '[data-testid="address"]',

                output: 'text',

                all: '1'

        	},

        	prices: {

                selector: '[data-testid="price-and-discounted-price"]',

                output: 'text',

                all: '1'

        	},

        	ratings: {

                selector: '[data-testid="review-score"]',

                output: 'text',

                all: '1'

        	},

        	thumbnails: {

                selector: '[data-testid="image"]',

                output: '@src',

                all: '1'

        	}

        })

    }

    const URL = "https://www.booking.com/searchresults.en-us.html?ss=Madeira+Islands&checkin=2023-01-13&checkout=2023-01-15"

    const response = await client.get(URL, api_params)

    if (response.success) {

        // Group the lists

    	  const listings = []

    	  for (let i = 0; i < response.response.data.names.length; i++) {

            listings.push({

               name: response.response.data.names[i],

               url: response.response.data.locations[i],

               address: response.response.data.addresses[i],

               price: response.response.data.prices[i],

               ratings: response.response.data.ratings[i],

               thumbnails: response.response.data.thumbnails[i]

            })

        }

        console.log(listings)

    } else {

        console.log(response.error.response.data)

    }

}

exampleUsage();

Fazit

In diesem Tutorial haben wir die Grundlagen des Webscrapings von Booking.com mit Node.js und Puppeteer behandelt. Wir haben Ihnen gezeigt, wie Sie Ihre Umgebung einrichten und Details zu Angeboten für Madeira, Portugal, extrahieren. Diese Techniken und Konzepte lassen sich jedoch auch auf andere Websites und Datenpunkte anwenden.

Web-Scraping kann sowohl für Unternehmen als auch für Datenwissenschaftler ein unglaublich nützliches Werkzeug sein. Durch das Sammeln von Daten von Booking.com können Sie wertvolle Einblicke in die Hotellerie gewinnen, die Konkurrenz einschätzen und vieles mehr. Es ist jedoch wichtig zu bedenken, dass Web-Scraping bei einigen Websites gegen die Nutzungsbedingungen verstoßen kann, und es ist immer ratsam, die spezifischen Richtlinien zu überprüfen, bevor Sie fortfahren.

Zwar ist es möglich, einen eigenen Web-Scraper zu erstellen, doch ist die Nutzung eines professionellen Dienstes oft die sicherere und effizientere Option, insbesondere bei größeren Projekten. Ein professioneller Scraper verfügt über das Fachwissen und die Ressourcen, um alle auftretenden Herausforderungen zu bewältigen und qualitativ hochwertige Ergebnisse zu liefern.

Wir hoffen, dass Ihnen dieses Tutorial gefallen hat und Sie sich nun in der Lage fühlen, wertvolle Daten von Booking.com mithilfe einer Node.js-Umgebung zu sammeln. Vielen Dank fürs Lesen!

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