Disponibilité Booking.com : un calendrier par date
Modélisez la disponibilité comme un calendrier par date, avec chambre et tarif en dimensions, consignez la requête que projette chaque page et gardez cinq états par cellule.
BotBrowser Team
Vous voulez la documentation structurée pour Réseau ?
Cet article fait partie de la bibliothèque éditoriale. Pour les étapes de configuration, la référence et les mises à jour continues, passez directement à la section docs.
Collecter la disponibilité sur Booking.com n’est pas un problème d’extraction de documents, car une page de disponibilité n’est pas un document. C’est une projection d’une requête : les dates, l’occupation, la chambre et le tarif demandés décident quelles cellules du calendrier existent sur la page. BotBrowser documente une sortie alignée géographiquement et des valeurs de paramètres régionaux issues du profil, de sorte qu’une comparaison de point de vente peut déclarer la région et la langue qu’elle représente. Il ne fournit pas de données de disponibilité, ne détient pas de stock, ne réserve pas de chambre et ne garantit pas qu’une requête renvoie deux fois le même calendrier. Préférez un flux partenaire ou affilié officiel lorsqu’il existe.
Résumé
- Une page de disponibilité est une projection de sa requête. Consignez la requête, sinon la page ne pourra plus être interprétée.
- Clé le calendrier par date, pas par page. Un séjour de trois nuits est trois lignes de date, et la date de départ est exclusive.
- Chambre et tarif sont des dimensions d’une ligne, pas des calendriers séparés. Deux tarifs sur la même date sont deux cellules, pas deux observations d’une cellule.
- Utilisez cinq états par cellule : disponible observé, fermé observé, hors de la fenêtre, absent de la réponse et non accepté. Une cellule absente n’est pas une chambre fermée.
- Préférez un flux partenaire ou affilié officiel lorsqu’il existe, et gardez les conditions de la plateforme comme autorité sur ce qui peut être collecté.
Sommaire
- La disponibilité comme calendrier
- La clé et les dimensions
- Ce que la page projette d’une requête
- Cinq états par cellule
- Consigner la requête avec l’observation
- La limite des conditions
- Conclusion pratique
La disponibilité comme calendrier
Une recherche d’hébergement répond à une question sur une plage de dates. La plage est l’unité que la source tarifie, et la nuit individuelle est l’unité sur laquelle un calendrier peut se clé. Mal poser cette relation est l’erreur de modélisation la plus courante en disponibilité, car une page affichant « à partir de 412 » pour trois nuits ressemble à une valeur unique alors qu’elle résume trois lignes qui peuvent chacune porter une disponibilité différente.
La date de départ est exclusive. Un séjour du 2026-12-10 au 2026-12-13 occupe les nuits du 10, du 11 et du 12, et le client part le 13. Traiter la date de départ comme une quatrième nuit produit un calendrier décalé d’un jour pour chaque séjour, et l’erreur reste invisible jusqu’à ce que quelqu’un compare une réservation de deux nuits et une de trois de la même chambre.
La disponibilité n’est pas non plus une propriété de l’établissement entier. Un hôtel peut avoir des chambres libres alors qu’un type précis est complet, et un type peut être libre alors que le tarif avec petit-déjeuner ne l’est pas. Le calendrier a donc besoin d’au moins deux dimensions avant qu’une cellule signifie quelque chose.
La clé et les dimensions
La clé est la date plus ce qui est observé. Les dimensions décrivent comment cette observation a été qualifiée. Les garder séparées permet de comparer deux captures sans mélanger silencieusement un type de chambre, un plan tarifaire ou un point de vente.
| Partie | Contenu | Pourquoi elle ne peut être repliée en une valeur de page |
|---|---|---|
date_key | Date ISO de la nuit, dans le fuseau de l’hôtel | Deux nuits sont deux observations, pas une |
room_code | Type de chambre ou d’unité tel que nommé par la source | Une suite complète ne ferme pas l’hôtel |
rate_code | Plan tarifaire tel que nommé par la source | Un tarif fermé ne ferme pas la chambre |
occupancy | Adultes et enfants demandés | L’occupation change le stock proposé |
Une clé (date, room, rate, occupancy) suffit à comparer deux observations de la même chose. Une clé réduite à (date) fusionne une suite et une chambre standard en une cellule, et la série obtenue montrera une chambre « rouvrant » à chaque changement de la catégorie la moins chère. Une clé (page) fusionne trois nuits en une valeur et perd la capacité de dire quelle nuit a changé.
Le fuseau horaire de l’établissement appartient aussi à la clé, mais comme propriété déclarée du calendrier et non comme dimension séparée. Une nuit est une notion locale, et une capture prise à travers un changement d’heure sans enregistrer le fuseau produira deux lignes qui ressemblent à une nuit dupliquée.
L’occupation mérite une note à part car elle change quel stock existe, pas seulement son prix. Une requête pour deux adultes peut renvoyer un type qu’une requête pour quatre ne peut pas voir, et la même chambre physique peut apparaître comme deux offres différentes avec des codes tarifaires différents. Consigner l’occupation auprès de la chambre et du tarif permet à une comparaison ultérieure de savoir si le changement vient du stock ou de la question posée.
Les règles de séjour minimum sont la dimension la plus silencieuse. Un établissement peut exiger deux nuits un week-end, si bien qu’une requête d’une nuit ne renvoie rien alors que la chambre est réellement libre pour deux nuits. Un calendrier qui enregistre la requête d’une nuit comme observed_closed a consigné un résultat de politique comme un fait de disponibilité. Lorsque la page énonce un séjour minimum, consignez-le comme dimension ou comme note ; sinon, traitez un résultat vide d’une nuit comme une observation avec sa requête déclarée et non comme une fermeture.
Devise et point de vente se placent auprès des quatre entrées tarifaires et non dans la clé du calendrier. Un code tarifaire peut exister en plusieurs devises et sous plusieurs règles de point de vente, et le montant différera alors que la disponibilité ne change pas. Gardez devise et point de vente dans l’enregistrement pour qu’une comparaison de prix ne soit pas prise pour une comparaison de disponibilité, et pour qu’un changement de devise ne ressemble pas à une chambre qui rouvre.
Ce que la page projette d’une requête
La documentation MDN de l’API URL décrit URL comme l’interface qui analyse et expose les composants d’une adresse, y compris ses paramètres de recherche. C’est la partie de la surface du navigateur dont ce problème a réellement besoin : une page de disponibilité rendue est sélectionnée par les paramètres de son adresse, donc l’adresse est une preuve sur la page et non une décoration autour d’elle.
Un même séjour admet plusieurs encodages de requête. Une plage de dates peut s’écrire en deux paramètres, en un paramètre de plage unique ou en segment de chemin, et une requête peut ajouter des paramètres de suivi qui ne changent pas le résultat. Normaliser la requête est donc la première étape pour rendre deux captures comparables, et cela doit se faire avant de demander la page, pas après.
// Constructed fixture: the same stay written two ways, then a changed check-in.
const raw = [
'https://example.test/hotel/alpha?checkin=2026-12-10&checkout=2026-12-13&adults=2&tracking=abc',
'https://example.test/hotel/alpha?stay=2026-12-10_2026-12-13&adults=2',
'https://example.test/hotel/alpha?checkin=2026-12-11&checkout=2026-12-14&adults=2',
];
const KEEP = ['checkin', 'checkout', 'adults', 'children', 'room', 'rate'];
const lines = raw.map(input => {
const url = new URL(input);
const stay = url.searchParams.get('stay');
const params = new Map();
if (stay) {
const [checkin, checkout] = stay.split('_');
params.set('checkin', checkin);
params.set('checkout', checkout);
}
for (const key of KEEP) {
const value = url.searchParams.get(key);
if (value) params.set(key, value);
}
const canonical = [...params.entries()]
.sort(([a], [b]) => a.localeCompare(b))
.map(([k, v]) => `${k}=${v}`)
.join('&');
return `canonical=${canonical} key=${params.get('checkin')}..${params.get('checkout')}`;
});
console.log(lines.join('\n'));
La sortie construite montre que les deux premières adresses se réduisent à une seule requête canonique, et que la troisième reste distincte parce que ses dates diffèrent.
canonical=adults=2&checkin=2026-12-10&checkout=2026-12-13 key=2026-12-10..2026-12-13
canonical=adults=2&checkin=2026-12-10&checkout=2026-12-13 key=2026-12-10..2026-12-13
canonical=adults=2&checkin=2026-12-11&checkout=2026-12-14 key=2026-12-11..2026-12-14
Le paramètre de suivi disparaît dans les deux premières lignes, et c’est le but : deux captures qui ne diffèrent que par une étiquette de campagne décrivent le même séjour et doivent se comparer comme une seule. La troisième ligne garde sa propre clé, car une arrivée décalée est une autre question même quand le nombre de nuits correspond.
Trois règles de normalisation rendent ce comportement fiable. Triez les paramètres conservés par nom pour que la forme canonique ne dépende pas de l’ordre utilisé par le site. Supprimez les paramètres dont la valeur n’affecte pas le résultat et gardez une liste explicite de ceux qui l’affectent, afin qu’un nouveau paramètre de suivi ne crée pas silencieusement une nouvelle série. Représentez la plage de dates d’une seule manière, en convertissant un paramètre de plage en deux dates explicites, pour que le choix d’encodage du site ne fuite jamais dans la clé.
Il existe aussi une frontière que le normaliseur ne peut pas franchir. Deux adresses qui semblent différentes peuvent décrire le même séjour via une redirection, et deux adresses qui semblent identiques peuvent se résoudre différemment à cause d’un cookie ou d’un état de compte. La requête canonique est donc une affirmation sur ce qui a été demandé, non une garantie sur ce qui a été rendu. Consignez la requête canonique et l’adresse finale après toute redirection, et traitez une divergence entre elles comme un constat et non comme du bruit.
Cinq états par cellule
Le travail sur la disponibilité échoue le plus souvent à la frontière entre « non disponible » et « non observé ». Un modèle binaire disponible/fermé force chaque cellule absente vers l’une de ces deux réponses, et les deux choix sont faux pour une cellule que la requête n’a jamais demandée.
| État | Ce qui a été observé | Ce que cela soutient |
|---|---|---|
observed_available | La requête a renvoyé une offre pour cette date, chambre et tarif | La cellule était disponible dans cette requête à ce moment |
observed_closed | La requête a renvoyé un signal explicite de complet ou de fermeture | La cellule était fermée dans cette requête à ce moment |
not_in_window | La fenêtre de la requête n’incluait pas cette date | Rien sur la cellule ; la fenêtre était bornée |
absent_in_window | La fenêtre couvrait la date, mais la réponse ne listait aucune cellule | Rien sur la cellule ; la réponse l’a omise |
unaccepted | Aucune réponse utilisable : vérification, erreur, délai dépassé, échec d’analyse | Rien sur la cellule ; l’observation a échoué |
Les deux états absents empêchent une série d’inventer des fermetures et décrivent des échecs différents. Si la capture n’a demandé que trois nuits, la quatrième nuit est not_in_window : hors de la fenêtre bornée, et non fermée. Si la fenêtre couvrait la date mais que la réponse ne listait aucune cellule, c’est absent_in_window : dans la fenêtre, non listée, toujours non fermée. Enregistrer l’un ou l’autre comme fermé fait croire que l’établissement a perdu une disponibilité qu’il n’a jamais signalée.
L’état unaccepted protège de l’erreur inverse. Une page de vérification, un 500 et un échec d’analyse produisent zéro cellule, et les traiter comme une disponibilité vide transforme un problème d’infrastructure en observation d’offre. Gardez-les dans leur propre état pour qu’un lecteur ultérieur voie quelle part du calendrier a réellement été observée.
La documentation MDN de l’API Performance décrit des interfaces du navigateur pour mesurer les temps et le chargement des ressources. Cela ne compte ici que pour la frontière entre une page acceptée et une page lente : une capture qui a abandonné avant le rendu du calendrier doit être consignée unaccepted, non comme un établissement sans chambres. Consigner le temps que la page a mis à se stabiliser auprès de l’état rend cette distinction auditable.
Une condition distincte se situe hors des cinq états et ne doit pas y être repliée : le calendrier a été observé, mais l’observation relève d’une portée différente de celle que la série revendique. Une capture prise avec un code tarifaire d’entreprise, une connexion membre ou une campagne promotionnelle peut montrer une disponibilité que la série publique ne peut pas, et mélanger les deux produit des lignes qui semblent comparables et ne le sont pas. Consignez la portée auprès de la requête et commencez une nouvelle série quand la portée change.
Les cinq états ont aussi besoin d’une règle de révision. Une cellule observée disponible lundi et fermée mardi est une transition, pas une contradiction, et l’enregistrement doit conserver les deux lignes avec leurs heures d’observation plutôt que d’écraser la première. Écraser perd la transition et empêche de distinguer un vrai changement d’une correction, ce qui est exactement la distinction dont un relecteur a besoin quand une série est contestée.
Enfin, gardez une granularité d’observation honnête. Une page peut rendre une vue mensuelle où seules certaines dates portent des cellules, et une capture qui enregistre le mois entier comme observé a revendiqué trop. Consignez quelles dates étaient réellement présentes dans la réponse, même quand la réponse est « la réponse listait trois des trente et une dates », et consignez ces dates comme absent_in_window plutôt que comme fermées.
Consigner la requête avec l’observation
Un enregistrement de capture de disponibilité doit porter la requête, car la page ne peut pas être interprétée sans elle. Les champs ci-dessous sont le minimum qui rend deux captures comparables.
| Champ | Contenu | Pourquoi il figure dans l’enregistrement |
|---|---|---|
canonical_query | Requête normalisée de l’étape précédente | Définit quel calendrier a été demandé |
property_ref | Identifiant de l’établissement propre à la source | Sépare deux établissements aux noms proches |
date_key | Date ISO de la nuit | Une ligne par nuit |
room_code | Type de chambre tel que nommé par la source | Sépare une suite d’une chambre standard |
rate_code | Plan tarifaire tel que nommé par la source | Sépare un tarif flexible d’un prépayé |
state | L’un des cinq états | Empêche l’absence d’être lue comme fermeture |
observed_at | Heure de capture en UTC | Ordonne les observations et borne l’exécution |
settle_ms | Temps de stabilisation de la page, si mesuré | Distingue une page lente d’une page absente |
Deux champs méritent une note. property_ref doit être un identifiant propre à la source et non un nom, car deux établissements de la même ville peuvent partager un nom et une chaîne peut en renommer un. settle_ms est facultatif mais utile : une capture qui a enregistré un état après 40 millisecondes a probablement lu un squelette plutôt qu’un calendrier, et il vaut la peine de le savoir avant de faire confiance à la ligne.
Le modèle de capture tarifaire applique la même discipline à un tarif unique plutôt qu’à un calendrier : les quatre entrées sont consignées par capture car une comparaison sans elles mesure l’environnement. La disponibilité a besoin de cela plus la clé de date, car un séjour couvre plusieurs lignes qui peuvent changer indépendamment.
La limite des conditions
Une page de réservation se trouve derrière une plateforme dont les conditions décident de ce qui peut être collecté. Ce n’est pas une contrainte technique qu’une meilleure configuration du navigateur supprimerait ; c’est la condition sous laquelle les données peuvent être utilisées. Là où un flux partenaire officiel, une interface d’affiliation ou un canal de distribution sous licence existe, il fournit la même disponibilité avec un schéma défini et un droit d’usage énoncé.
La RFC 9110 définit la sémantique HTTP, y compris la mise en cache et l’en-tête Vary, qui indique à un cache quels champs de la requête ont influé sur la représentation. C’est le mécanisme par lequel une page dit que son contenu dépend de plus que son chemin, et c’est un rappel utile qu’une réponse de disponibilité est négociée plutôt que figée. Elle ne dit rien sur le fait qu’un site donné autorise la collecte, et aucun en-tête ne fait disparaître une question de conditions.
Le modèle d’annonces immobilières trace la même ligne pour les données de biens : une occurrence d’annonce, le bien physique et une offre sont distincts, et une carte absente n’est pas une vente. La disponibilité a la même forme, avec une plage de dates au lieu d’un bien, et la même règle s’applique : une observation n’est pas une conclusion.
Deux limites pratiques en découlent. D’abord, observer n’est pas réserver : charger un calendrier et consigner ce qu’il a montré est un acte différent de bloquer une chambre, et le second est entièrement hors périmètre. Ensuite, une différence entre deux captures est une observation, non la preuve d’une violation de politique par la plateforme. Ces conclusions appartiennent à qui détient le stock et l’accord.
Questions fréquentes
Un séjour de trois nuits est-il une seule valeur de disponibilité ?
Non. Ce sont trois lignes de date, et chacune peut porter un état différent. Une page qui résume le séjour montre une projection ; le résumé doit donc être décomposé avant d’être comparé nuit par nuit.
Une cellule absente signifie-t-elle que la chambre est indisponible ?
Non. Soit la fenêtre ne couvrait pas la date (not_in_window), soit elle la couvrait et la réponse ne listait aucune cellule (absent_in_window), soit la réponse n’a pas été acceptée (unaccepted). Gardez les trois séparés de observed_closed pour qu’aucun ne soit lu comme une fermeture.
Le type de chambre et le tarif appartiennent-ils à la clé ?
Oui, avec la date, car une suite complète ne ferme pas l’hôtel et un tarif fermé ne ferme pas la chambre. Les replier en une valeur au niveau de la page fusionne des observations qui doivent rester séparées.
BotBrowser fournit-il des données de disponibilité ou réserve-t-il des chambres ?
Non. Il fournit des entrées de navigateur documentées, dont une sortie alignée géographiquement et des valeurs de paramètres régionaux issues du profil, pour qu’une comparaison déclare sa région. Il ne fournit pas de disponibilité, ne détient pas de stock, ne réserve pas de chambre et ne garantit pas un résultat.
Sources
- API URL de MDN
- API Performance de MDN
- RFC 9110 sémantique HTTP
- Base GeoIP de BotBrowser
- Configuration des profils BotBrowser
Conclusion pratique
Modélisez la disponibilité comme un calendrier clé par date, avec chambre, tarif et occupation en dimensions, et traitez la date de départ comme exclusive. Normalisez la requête avant de demander la page et consignez-la à chaque capture, car la page est une projection de cette requête et non un document autonome. Gardez cinq états par cellule pour que l’absence et l’échec d’observation ne deviennent jamais des fermetures. Là où un flux partenaire ou affilié officiel existe, utilisez-le, et laissez les conditions de la plateforme décider ce que l’exécution de navigateur peut collecter.
Cet article fait partie du guide : Vue d’ensemble de la configuration proxy : carte des décisions réseau
Articles Connexes
Prix des vols : fixer quatre entrées
RéseauLimites de scraping : 429, Retry-After et concurrence
RéseauCAPTCHA pendant le scraping : diagnostiquer le changement
PlateformeFormatage des dates et portabilité des fuseaux horaires
RéseauRotation de proxy : limites de session en scraping
RéseauCloudflare et DataDome : réponses au scraping
Exécutez la même vérification dans BotBrowser
Chargez un profil, gardez dans le navigateur les signaux que vous venez de lire, puis confirmez le résultat sur votre propre machine avant le déploiement.