Booking.com est l'un des plus grands marketplaces de voyage sur le web ouvert, et ses pages publiques de résultats de recherche concentrent de nombreux signaux structurés : noms d'hôtels et de propriétés, prix par nuit, scores d'avis des clients, quartiers, et lien vers chaque annonce. Les équipes d'intelligence tarifaire l'utilisent pour comparer les tarifs entre les villes, les chercheurs étudient l'offre et la demande par destination, et les planificateurs de voyages comparent les propriétés côte à côte. Tout cela figure sur la page de recherche publique sous la forme d'une mise en page de cartes prévisible.
Ce guide vous montre comment scraper Booking.com avec JavaScript et Node.js en utilisant Cheerio. Vous construisez un petit scraper exécutable qui récupère une page publique de résultats de recherche Booking.com via l'API Crawling, analyse le nom de la propriété, le prix, le score d'avis, l'emplacement et l'URL de l'annonce pour chaque carte, puis exporte le résultat en JSON et CSV. L'ensemble de ce tutoriel reste limité aux données d'annonces d'hôtels publiques, et la section sur la légalité, vers la fin, n'est pas du remplissage standard, lisez-la avant de pointer ce scraper sur un volume réel.
Ce que vous allez construire
Un script Node.js qui prend une URL publique de résultats de recherche Booking.com, récupère le HTML rendu via l'API Crawling, et extrait un enregistrement structuré pour chaque carte de propriété sur la page. Nous utilisons une recherche d'hôtels à San Francisco comme exemple fil conducteur et récupérons ces champs par annonce :
- Nom le nom de l'hôtel ou de la propriété affiché sur la carte, par exemple "Hotel Zephyr San Francisco".
- Prix le prix par nuit affiché, comme "US$592".
- Note le score public des avis clients, quand Booking.com en affiche un pour cette propriété.
- Emplacement le quartier et la ville où la propriété est annoncée.
- Lien l'URL vers la page individuelle de la propriété.
Pourquoi une requête simple échoue sur Booking.com
Si vous interrogez une URL de recherche Booking.com avec un client HTTP basique, vous obtenez rarement les cartes de propriétés en retour. Deux facteurs jouent contre vous. Premièrement, Booking.com affiche la liste des résultats dans le navigateur avec JavaScript, donc le HTML initial est une coquille presque vide jusqu'à ce que les scripts de la page s'exécutent. Deuxièmement, Booking.com surveille le trafic automatisé : les adresses IP de centres de données et les schémas de requêtes qui ne ressemblent pas à un vrai navigateur se heurtent à un CAPTCHA, sont limités en débit ou bloqués avant même d'atteindre les annonces rendues.
Un scraper fonctionnel a donc besoin de deux choses en une seule requête : un navigateur qui rend réellement la page, et une adresse IP que la plateforme interprète comme un visiteur réel. Vous pouvez assembler cela vous-même avec un navigateur headless et un pool de proxies résidentiels rotatifs, mais maintenir cet ensemble en bon état de fonctionnement représente l'essentiel du travail. L'API Crawling combine les deux en un seul appel : vous lui envoyez l'URL, elle rend la page derrière une IP de confiance, et vous renvoie du HTML prêt à analyser avec Cheerio.
L'API Crawling vous donne deux tokens : un normal et un JavaScript. Booking.com nécessite que la page soit rendue dans un vrai navigateur, donc utilisez votre token JavaScript pour chaque requête dans ce guide. Le token normal renvoie la coquille non rendue et vos sélecteurs reviendront vides.
Prérequis
Quelques éléments doivent être en place avant d'écrire du code. Aucun ne prend beaucoup de temps.
JavaScript et Node.js de base. Vous devez être à l'aise pour écrire et exécuter un script Node, installer des packages avec npm, et travailler avec du code asynchrone. Pour un tutoriel plus complet, notre guide sur la construction d'un web scraper avec Node.js couvre les bases.
Node.js 16 ou supérieur. Confirmez votre version avec node --version. Si vous ne l'avez pas, installez-le depuis le site Node.js ou via un gestionnaire de version comme nvm.
Un compte Crawlbase et un token. Inscrivez-vous, ouvrez votre tableau de bord, et copiez votre token JavaScript depuis la page des docs de votre compte. Le niveau gratuit vous donne jusqu'à 20 000 requêtes sans carte bancaire, et vous ne payez que pour les requêtes réussies. Traitez le token comme un mot de passe : il authentifie vos requêtes, gardez-le hors du contrôle de version.
Configurer le projet
Créez un dossier de projet, initialisez-le, et installez les deux bibliothèques dont le scraper a besoin.
node --version mkdir booking-scraper && cd booking-scraper npm init -y npm install crawlbase cheerio
Deux dépendances font le travail : crawlbase est le client Node officiel pour l'API Crawling, et cheerio analyse le HTML renvoyé avec une API de style jQuery afin que vous puissiez extraire des champs individuels par sélecteur CSS. Créez un fichier nommé scraper.js dans ce dossier et ajoutez le code des étapes ci-dessous.
Étape 1 : Récupérer la page de recherche rendue
Commencez par obtenir la page terminée. Importez la classe CrawlingAPI, initialisez-la avec votre token JavaScript, et demandez une URL publique de résultats de recherche Booking.com. Vérifier le code de statut avant d'analyser rend les échecs visibles plutôt que silencieux.
const { CrawlingAPI } = require('crawlbase'); const api = new CrawlingAPI({ token: 'YOUR_CRAWLBASE_TOKEN' }); const bookingPageURL = 'https://www.booking.com/searchresults.html?ss=San+Francisco&checkin=2025-12-25&checkout=2025-12-31&group_adults=2&no_rooms=1&group_children=0&selected_currency=USD'; api .get(bookingPageURL) .then((response) => { if (response.statusCode === 200) { console.log(response.body.slice(0, 500)); } }) .catch((error) => console.error('API request error:', error));
Exécutez le script avec node scraper.js et vous devriez voir de vraies balises de propriétés Booking.com en haut du corps, et non une coquille allégée. Cela confirme que le rendu fonctionne avant d'écrire un seul sélecteur. L'API Crawling utilise le token JavaScript que vous avez fourni pour rendre la page dans un vrai navigateur, de sorte que les cartes de propriétés sont présentes dans le HTML que vous récupérez.
Cette première requête vient de renvoyer une page de recherche Booking.com entièrement rendue sans navigateur headless ni proxy de votre côté. L'API Crawling exécute la page dans un vrai navigateur, fait tourner des adresses IP résidentielles côté serveur et gère les CAPTCHAs que Booking.com lance aux scrapers, vous obtenant ainsi du HTML terminé en un seul appel. Pointez-la sur une recherche d'hôtels publique avec le niveau gratuit en premier, puis ajoutez votre parser.
Étape 2 : Analyser chaque carte de propriété avec Cheerio
Avec le HTML rendu en main, chargez-le dans Cheerio et parcourez les cartes de propriétés. Booking.com enveloppe chaque annonce dans un élément marqué data-testid="property-card", donc vous sélectionnez toutes les cartes, puis lisez le nom, l'emplacement, le score d'avis, le prix et le lien de l'annonce à l'intérieur en utilisant les propres attributs data-testid de la page. Lire chaque champ de manière défensive évite qu'une valeur manquante ne fasse planter l'exécution.
const cheerio = require('cheerio'); function parseDataFromHTML(html) { const $ = cheerio.load(html); const properties = []; const cardSelector = '[data-testid="property-card"]'; $(cardSelector).each((_, card) => { const currentCard = $(card); const extractText = (selector) => currentCard.find(selector).text().trim(); const name = extractText('[data-testid="title"]'); const location = extractText('[data-testid="address"]'); const rating = extractText( '[data-testid="review-score"] div.a3b8729ab1.d86cee9b25', ); const price = extractText( 'span[data-testid="price-and-discounted-price"]', ); const link = currentCard .find('[data-testid="title-link"]') .attr('href'); if (name) { properties.push({ name, price: price || 'Price not available', rating: rating || 'Rating not available', location, link: link || '', }); } }); return properties; }
Quelques détails assurent la fidélité à la page. Chaque annonce se trouve dans un élément [data-testid="property-card"]. À l'intérieur d'une carte, le nom vient de [data-testid="title"], l'emplacement de [data-testid="address"], le score d'avis du bloc de score à l'intérieur de [data-testid="review-score"], le prix de span[data-testid="price-and-discounted-price"], et l'URL de l'annonce du href de l'ancre [data-testid="title-link"]. Privilégier d'abord les hooks stables data-testid, et ne tomber en retrait sur les noms de classes générés que quand vous y êtes obligé, maintient le parser plus stable à mesure que le balisage évolue.
Les noms de classes générés par Booking.com (les suffixes de style a3b8729ab1 ci-dessus) changent sans préavis, et même les hooks data-testid sont parfois renommés. Traitez les sélecteurs comme un modèle de départ, pas comme un contrat. Quand un champ revient vide, inspectez à nouveau la page en direct avec les outils de développement de votre navigateur et mettez à jour le sélecteur. Une maintenance périodique des sélecteurs est normale pour tout scraper en production, et n'est pas le signe que quelque chose est cassé.
Étape 3 : Assembler le script complet avec export JSON et CSV
Reliez maintenant la récupération et l'analyse en un script exécutable, puis écrivez les enregistrements sur disque en JSON et en CSV. L'ancien guide sauvegardait le HTML brut dans un fichier entre les étapes, mais regrouper la récupération et l'analyse en une seule exécution réduit les composants mobiles.
const fs = require('fs'); const { CrawlingAPI } = require('crawlbase'); const cheerio = require('cheerio'); const api = new CrawlingAPI({ token: 'YOUR_CRAWLBASE_TOKEN' }); async function crawl(pageUrl) { const response = await api.get(pageUrl); if (response.statusCode === 200) return response.body; console.error(`Request failed: ${response.statusCode}`); return null; } function toCsv(rows) { const headers = ['name', 'price', 'rating', 'location', 'link']; const escape = (value) => `"${String(value).replace(/"/g, '""')}"`; const lines = [headers.join(',')]; for (const row of rows) { lines.push(headers.map((h) => escape(row[h])).join(',')); } return lines.join('\n'); } async function main() { const url = 'https://www.booking.com/searchresults.html?ss=San+Francisco&checkin=2025-12-25&checkout=2025-12-31&group_adults=2&no_rooms=1&group_children=0&selected_currency=USD'; const html = await crawl(url); if (!html) return; const properties = parseDataFromHTML(html); fs.writeFileSync('booking.json', JSON.stringify(properties, null, 2)); fs.writeFileSync('booking.csv', toCsv(properties)); console.log(`Saved ${properties.length} properties to JSON and CSV`); } main();
Collez la fonction parseDataFromHTML de l'étape 2 dans le même fichier pour que main puisse l'appeler. Exécutez-le avec node scraper.js et vous obtenez deux fichiers : booking.json avec les enregistrements structurés complets et booking.csv prêt à ouvrir dans un tableur. L'assistant toCsv entoure chaque champ de guillemets et double les guillemets intégrés, ce qui est important ici car les noms de propriétés et les labels de quartier contiennent fréquemment des virgules.
À quoi ressemble la sortie
Le fichier JSON contient un objet par propriété, chacun avec le nom, le prix, le score d'avis public, l'emplacement et le lien de l'annonce. Les valeurs ci-dessous sont illustratives ; votre exécution reflète ce qui est en ligne pour vos dates de recherche.
[ { "name": "Hotel Zephyr San Francisco", "price": "US$592", "rating": "8.3", "location": "Fisherman's Wharf, San Francisco", "link": "https://www.booking.com/hotel/us/zephyr-san-francisco.html" }, { "name": "Club Quarters Hotel Embarcadero, San Francisco", "price": "US$554", "rating": "8.0", "location": "Financial District, San Francisco", "link": "https://www.booking.com/hotel/us/club-quarters-san-francisco.html" } ]
Le CSV reproduit les mêmes lignes de propriétés avec une ligne d'en-tête, il s'intègre donc directement dans Excel, Google Sheets, ou tout pipeline de données qui lit des fichiers délimités.
name,price,rating,location,link "Hotel Zephyr San Francisco","US$592","8.3","Fisherman's Wharf, San Francisco","https://www.booking.com/hotel/us/zephyr-san-francisco.html" "Club Quarters Hotel Embarcadero, San Francisco","US$554","8.0","Financial District, San Francisco","https://www.booking.com/hotel/us/club-quarters-san-francisco.html"
Gérer la pagination
Une page de recherche est une démonstration ; un vrai travail récupère chaque page de résultats. Booking.com pagine ses URL de recherche avec un paramètre offset qui saute un nombre fixe de propriétés par page, vous pouvez donc boucler sur les offsets, récupérer chaque page via l'API Crawling, l'analyser avec la même fonction, et arrêter quand une page ne renvoie aucune carte. Comme toutes les pages de résultats partagent la même structure de cartes, le parser que vous avez déjà écrit fonctionne sur toutes sans modifications.
async function scrapeAllPages(baseUrl, maxPages) { const allProperties = []; const perPage = 25; for (let page = 0; page < maxPages; page++) { // Booking.com skips results with an offset parameter const pageUrl = `${baseUrl}&offset=${page * perPage}`; const html = await crawl(pageUrl); if (!html) break; const properties = parseDataFromHTML(html); if (properties.length === 0) break; // no more results allProperties.push(...properties); console.log(`Page ${page + 1}: ${properties.length} properties`); // Pace requests so you stay under the rate limit await new Promise((r) => setTimeout(r, 2000)); } return allProperties; }
La taille exacte de page et le paramètre peuvent changer, vérifiez donc quelques vrais liens "page suivante" dans votre navigateur et correspondez au schéma. Les bonnes pratiques s'appliquent à toute cible : bouclez jusqu'à l'épuisement des résultats, et introduisez un court délai entre les requêtes pour ne pas marteler le site. Pour plus d'informations sur les pages rendues et à fort contenu JavaScript comme celle-ci, consultez notre guide sur le crawling de sites web JavaScript.
Rester non bloqué
Même avec le rendu géré, Booking.com surveille le trafic ayant l'aspect d'un scraper. Quelques habitudes maintiennent une exécution en bonne santé, et elles s'appliquent à toute cible commerciale difficile.
- Cadencez vos requêtes. Introduisez un délai entre les récupérations de pages plutôt que de marteler la recherche en boucle serrée. Espacer les requêtes est le facteur unique le plus important pour rester sous les limites de débit de Booking.com.
- Misez sur la rotation. Un pool d'adresses IP résidentielles répartit les requêtes sur de nombreuses adresses d'utilisateurs réels, de sorte qu'aucune ne déclenche une limite ou un CAPTCHA. L'API Crawling gère cela pour vous ; si vous construisez votre propre stack, c'est la partie à soigner.
- Lisez les codes de statut. Une exécution qui commence à renvoyer des challenges ou des réponses non-200 vous signale que le débit ou le tier d'IP actuel n'est plus suffisant. Traitez cela comme un signal pour reculer, pas comme du bruit à ignorer.
Pour le guide complet, consultez comment scraper des sites web sans être bloqué. Si vous souhaitez des données d'annonces similaires d'une autre plateforme de voyage, le même schéma récupération-puis-analyse s'applique directement au scraping des prix Airbnb et au scraping d'Expedia avec JavaScript. Pour comparer ces tarifs entre sites, notre guide sur le web scraping pour l'intelligence tarifaire aborde le côté analyse.
Est-il légal de scraper Booking.com ?
La question de savoir si le scraping de Booking.com est autorisé dépend des conditions d'utilisation de Booking.com, de votre juridiction, et de ce que vous faites avec les données. Les conditions de Booking.com restreignent l'accès automatisé, donc le scraping peut aller à l'encontre de ces conditions quelle que soit la prudence de vos outils. Aucun code ici ne change cela ; il rend simplement la partie technique fonctionnelle. Lisez les Conditions d'utilisation de Booking.com et son robots.txt, respectez toute attente de débit qu'ils indiquent, et traitez les deux comme la limite de ce que vous collectez.
Ce guide est délibérément limité aux données publiques d'annonces hôtelières : le nom de la propriété, le prix affiché, le score d'avis agrégé, le quartier et le lien de l'annonce que tout le monde peut voir sur une page de recherche sans se connecter. Il s'agit d'informations factuelles sur une propriété, pas de données personnelles. D'autres contenus sont hors de portée : les avis individuels des clients et leurs auteurs constituent des données personnelles, tout ce qui se trouve derrière une connexion ou un processus de réservation est hors limites, et les photos et descriptions de propriétés sont des œuvres protégées par le droit d'auteur que vous ne devez pas redistribuer en masse. Si des données personnelles entrent en jeu, la loi sur la vie privée telle que le RGPD et le CCPA s'applique, donc limitez votre collecte aux champs agrégés et non personnels ci-dessus.
Si votre projet nécessite plus que des annonces publiques, la bonne voie est une voie sanctionnée, pas un scraper plus habile. Booking.com gère des programmes officiels d'affiliation et de partenariat, y compris une API Demand, qui exposent des données de propriétés, de disponibilités et de tarifs dans des conditions claires avec des règles d'attribution et des droits commerciaux définis. Ce sont les bons outils quand vous avez besoin de gros volumes, d'une structure garantie, ou du droit de réutiliser les données commercialement. En cas de doute sur la légitimité d'une utilisation, obtenez une autorisation ou un accord de données plutôt que de supposer que le silence vaut consentement.
Points clés
- Booking.com rend les annonces côté client et bloque fortement. Une requête simple renvoie une coquille vide ou un CAPTCHA, vous devez donc rendre la page derrière une IP de confiance, en utilisant le token JavaScript, avant de l'analyser.
- L'API Crawling fait les deux en un seul appel. Elle rend la page dans un vrai navigateur, fait tourner des IP résidentielles et gère les CAPTCHAs, renvoyant du HTML terminé que vous analysez avec Cheerio.
-
Cheerio extrait les champs. Sélectionnez chaque
[data-testid="property-card"], puis lisez le nom, le prix, le score d'avis, l'emplacement et le lien de l'annonce, en attendant que les noms de classes générés évoluent. - Paginéz et exportez. Bouclez sur le paramètre offset de Booking.com jusqu'à épuisement des résultats, cadencez vos requêtes, et écrivez des enregistrements structurés en JSON et en CSV.
- Restez sur les données publiques. Collectez uniquement les annonces d'hôtels publiques, traitez les avis individuels des clients et leurs auteurs comme des données personnelles, respectez les CGU et le robots.txt, et préférez l'API officielle partenaire de Booking.com pour les gros volumes ou l'usage commercial.
Foire aux questions
Puis-je construire un scraper Booking.com dans un langage autre que JavaScript ?
Oui. Ce guide utilise JavaScript avec Cheerio, mais la même approche fonctionne dans n'importe quel langage. L'API Crawling dispose de bibliothèques et de SDK pour plusieurs langages, vous récupérez donc le HTML rendu de la même manière et l'analysez avec le parser HTML que votre stack préfère, comme BeautifulSoup en Python. Les sélecteurs et les champs restent les mêmes ; seule la syntaxe d'analyse change.
Pourquoi une requête simple renvoie-t-elle des données incomplètes depuis Booking.com ?
Parce que Booking.com affiche sa liste de propriétés côté client avec JavaScript et challenge le trafic automatisé avec des CAPTCHAs. Une requête HTTP brute depuis une adresse IP de centre de données renvoie généralement une coquille vide ou une page de blocage plutôt que les cartes de propriétés. Pour obtenir une page complète, vous devez la rendre derrière une IP de confiance, ce que l'API Crawling gère pour vous quand vous utilisez le token JavaScript.
Mes sélecteurs renvoient des valeurs vides. Qu'est-ce qui a changé ?
Presque certainement le balisage de Booking.com. Ses noms de classes générés comme a3b8729ab1 changent sans préavis, et même les hooks data-testid sont parfois renommés, donc des sélecteurs qui fonctionnaient le mois dernier peuvent se casser. Inspectez à nouveau une page en direct avec les outils de développement de votre navigateur, mettez à jour les sélecteurs dans parseDataFromHTML, et vous êtes de retour en action. Une maintenance périodique des sélecteurs est normale pour tout scraper en production.
Vais-je être bloqué en scrapant Booking.com ?
C'est possible si vous envoyez trop de requêtes trop rapidement depuis une seule adresse. L'API Crawling réduit ce risque en alternant les IP résidentielles et en gérant les CAPTCHAs pour vous, mais vous devez quand même cadencer vos requêtes, ajouter des délais entre les pages, et surveiller les codes de statut afin de reculer quand des challenges apparaissent. Ces habitudes sont importantes sur toute cible commerciale difficile.
Puis-je scraper les avis individuels des clients et les noms des auteurs ?
Cela sort du cadre de ce guide, et pour de bonnes raisons. Les avis individuels et leurs auteurs constituent des données personnelles, ce qui fait entrer en jeu la loi sur la vie privée comme le RGPD et le CCPA. Utilisez le score d'avis agrégé des clients comme signal sur une propriété, ne construisez pas de profils d'auteurs d'avis individuels, et ne republiez pas l'avis d'une personne lié à son identité. Pour tout ce qui va au-delà des annonces publiques, utilisez le programme officiel partenaire de Booking.com.
Booking.com dispose-t-il d'une API officielle ?
Oui. Booking.com gère des programmes officiels d'affiliation et de partenariat, y compris une API Demand, qui exposent des données de propriétés, de disponibilités et de tarifs dans des conditions claires, avec des règles d'attribution et des droits commerciaux définis. Si vous avez besoin de gros volumes, d'une structure garantie, ou du droit de réutiliser les données commercialement, cette voie sanctionnée est la bonne. Ce scraper de données publiques convient mieux à la recherche, au prototypage et à l'analyse à plus petite échelle où un accord officiel n'est pas justifié.
Crawlez n'importe quel site à grande échelle, sans combattre l'infrastructure.
Crawlbase gère les proxies, les empreintes et les CAPTCHA afin que votre équipe livre des pipelines de données au lieu de maintenir la plomberie de crawl. 1 000 requêtes gratuites, sans carte requise.
