Retour au Centre de connaissances
Réseau

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

Documentation

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.

Un séjour construit du 2026-12-10 au 2026-12-13 se projette en trois lignes de date, avec chambre et tarif comme dimensions sur chaque ligne, cinq états possibles par cellule et un enregistrement de capture qui conserve la requête auprès de l’observation.

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

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.

PartieContenuPourquoi elle ne peut être repliée en une valeur de page
date_keyDate ISO de la nuit, dans le fuseau de l’hôtelDeux nuits sont deux observations, pas une
room_codeType de chambre ou d’unité tel que nommé par la sourceUne suite complète ne ferme pas l’hôtel
rate_codePlan tarifaire tel que nommé par la sourceUn tarif fermé ne ferme pas la chambre
occupancyAdultes et enfants demandésL’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.

ÉtatCe qui a été observéCe que cela soutient
observed_availableLa requête a renvoyé une offre pour cette date, chambre et tarifLa cellule était disponible dans cette requête à ce moment
observed_closedLa requête a renvoyé un signal explicite de complet ou de fermetureLa cellule était fermée dans cette requête à ce moment
not_in_windowLa fenêtre de la requête n’incluait pas cette dateRien sur la cellule ; la fenêtre était bornée
absent_in_windowLa fenêtre couvrait la date, mais la réponse ne listait aucune celluleRien sur la cellule ; la réponse l’a omise
unacceptedAucune réponse utilisable : vérification, erreur, délai dépassé, échec d’analyseRien 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.

ChampContenuPourquoi il figure dans l’enregistrement
canonical_queryRequête normalisée de l’étape précédenteDéfinit quel calendrier a été demandé
property_refIdentifiant de l’établissement propre à la sourceSépare deux établissements aux noms proches
date_keyDate ISO de la nuitUne ligne par nuit
room_codeType de chambre tel que nommé par la sourceSépare une suite d’une chambre standard
rate_codePlan tarifaire tel que nommé par la sourceSépare un tarif flexible d’un prépayé
stateL’un des cinq étatsEmpêche l’absence d’être lue comme fermeture
observed_atHeure de capture en UTCOrdonne les observations et borne l’exécution
settle_msTemps 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

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.

#Disponibilité Hôtelière#Données De Disponibilité#Automatisation Du Navigateur

Cet article fait partie du guide : Vue d’ensemble de la configuration proxy : carte des décisions réseau

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.