Airbnb est l'une des plus grandes plateformes de séjours courts du web, et ses pages d'annonces publiques contiennent exactement les champs structurés qui alimentent les études de marché, le suivi des prix et les comparateurs de voyages : le titre de l'annonce, le prix par nuit, la note et le nombre d'avis, la localisation, et les équipements mis en avant. Pour quiconque étudie les tarifs nocturnes dans une ville ou suit l'évolution d'un marché, ces données publiques sont la matière première, et les collecter manuellement sur des dizaines de séjours est lent et source d'erreurs.
Ce guide vous montre comment scraper les annonces Airbnb avec Python de manière fiable. Vous construisez un petit scraper fonctionnel qui récupère les pages de recherche Airbnb rendues via la Crawling API, parse les champs d'annonce voulus avec BeautifulSoup, gère la pagination et exporte du JSON et du CSV propres. L'ensemble du guide se limite aux données d'annonces publiques : aucune information personnelle sur les hôtes ou les voyageurs, aucun avis individuel lié à une personne nommée. La section sur la légalité vers la fin n'est pas un remplissage de formulaire, lisez-la avant de pointer ce scraper sur un volume réel.
Ce que vous allez construire
Un script Python qui prend une URL de recherche Airbnb publique pour un lieu et des dates de séjour, collecte les cartes d'annonce sur chaque page de résultats et extrait un enregistrement structuré par annonce. L'exemple filé est les séjours aux États-Unis, mais la même approche fonctionne pour n'importe quelle URL de recherche publique. Nous extrayons ces champs :
- Titre le titre de l'annonce affiché sur la carte, par exemple "Cabin in Woodstock".
- Prix le prix par nuit tel qu'affiché sur l'annonce.
- Note la note globale des voyageurs et le nombre d'avis à côté.
- Localisation le nom du lieu extrait du titre de l'annonce.
- Équipements les principaux équipements mis en avant sur la carte, comme une piscine, le wifi ou une cuisine.
- Lien l'URL canonique de la page de l'annonce.
Chacun de ces champs est public et non personnel. Le scraper ne touche jamais le nom d'un hôte, le profil d'un voyageur, des messages privés ou un avis attribué à une personne nommée.
Pourquoi une requête simple échoue sur Airbnb
Si vous demandez une URL de recherche Airbnb avec un client HTTP basique, vous obtenez une réponse avec le statut 200 et presque aucune donnée d'annonce dans le corps. Deux choses jouent contre vous. Premièrement, Airbnb affiche ses résultats de recherche dans le navigateur via JavaScript, de sorte que le HTML initial est une coquille vide qui ne se remplit qu'après l'exécution des scripts de la page. Parsez cette première réponse et vous capturez une grille vide plutôt que les cartes d'annonce. Deuxièmement, Airbnb signale rapidement le trafic automatisé : les IP de datacenter et les schémas de requêtes qui ne ressemblent pas à un vrai navigateur se retrouvent throttlés, bloqués par IP ou mis en défi avant même d'atteindre le contenu rendu.
Un scraper Airbnb fonctionnel a donc besoin de deux choses en une seule requête : un navigateur qui rend réellement la page, et une IP que la plateforme lit comme un vrai visiteur. Vous pouvez assembler cela vous-même avec un navigateur headless plus un pool de proxies résidentiels rotatifs, mais les relier et les maintenir en bonne santé représente l'essentiel du travail. La Crawling API combine les deux en un seul appel : vous lui envoyez l'URL avec un token JavaScript, elle rend la page derrière une IP de confiance, et vous renvoie le HTML final à parser.
Crawlbase propose deux types de tokens. Le token normal récupère le HTML statique ; le token JavaScript (JS) rend d'abord la page dans un vrai navigateur. Airbnb remplit sa grille de recherche côté client, vous avez donc besoin du token JS ici. Le token normal renvoie la même coquille vide qu'une requête simple, et il y a peu d'utilité à parser quoi que ce soit dedans.
Prérequis
Vous avez besoin de quelques éléments en place avant d'écrire du code. Aucun ne prend longtemps.
Python de base. Vous devez être à l'aise pour écrire et exécuter un script Python et installer des paquets avec pip. Si vous êtes nouveau côté parsing, le guide BeautifulSoup est un bon complément à ce tutoriel.
Python 3.8 ou version ultérieure. Confirmez votre version avec python --version. Si vous ne l'avez pas, installez-le depuis python.org ou via une distribution comme Anaconda, et assurez-vous que Python est dans votre PATH.
Un compte Crawlbase et un token JS. Inscrivez-vous, ouvrez votre tableau de bord et copiez votre token JavaScript (JS) depuis la page de docs du compte. Crawlbase inclut jusqu'à 20 000 requêtes gratuites pour démarrer, ce qui est largement suffisant pour suivre ce guide, et vous ne payez que pour les requêtes réussies. Traitez le token comme un mot de passe : il authentifie vos requêtes, donc gardez-le hors du contrôle de version.
Configurer le projet
Créez un environnement virtuel pour isoler les dépendances du projet, puis installez les bibliothèques dont le scraper a besoin.
python --version python -m venv airbnb_env source airbnb_env/bin/activate pip install crawlbase beautifulsoup4
Sous Windows, activez l'environnement avec airbnb_env\Scripts\activate à la place de la ligne source. Deux dépendances font le travail : crawlbase est le client officiel de la Crawling API, et beautifulsoup4 parse le HTML renvoyé pour extraire les champs individuels par sélecteur CSS. json et csv sont fournis avec la bibliothèque standard, il n'y a donc rien de plus à installer pour l'étape d'export.
Étape 1 : récupérer une page de recherche Airbnb rendue
Commencez par obtenir une page finie. Importez la classe CrawlingAPI, initialisez-la avec votre token JS et demandez une URL de recherche Airbnb. Airbnb charge les résultats de manière asynchrone, donc passez ajax_wait et page_wait pour attendre le contenu dynamique avant que la page soit capturée. Vérifier le cb_status (legacy pc_status) de Crawlbase avant de parser rend les échecs visibles plutôt que silencieux.
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")
Les deux options d'attente ont leur importance pour une cible rendue côté client comme Airbnb. ajax_wait demande à l'API d'attendre la fin du chargement du contenu asynchrone, et page_wait maintient un délai fixe en millisecondes après le chargement pour que les cartes qui apparaissent tardivement soient présentes avant que la page ne soit capturée. Cinq secondes est un bon point de départ ; augmentez si les résultats reviennent peu fournis. L'URL de recherche contient le lieu, les dates d'arrivée et de départ et le nombre d'adultes, comme la recherche Airbnb elle-même. Lancez le script avec python airbnb_scraper.py et vous devriez voir de vraies balises de recherche Airbnb, et non la coquille qu'une requête simple renverrait. Cela confirme que le rendu fonctionne avant d'écrire le moindre sélecteur.
Airbnb nécessite une page rendue derrière une IP de confiance, en un seul appel, ce qui est exactement ce que configurent les options ajax_wait et page_wait ci-dessus. La Crawling API prend un token JS, exécute la page dans un vrai navigateur, fait tourner des IP résidentielles côté serveur et vous remet le HTML final, vous évitant de faire tourner vous-même une flotte headless et un pool de proxies. Pointez-la sur une page de recherche publique sur le niveau gratuit d'abord, et ne payez que pour les requêtes réussies.
Étape 2 : inspecter les cartes d'annonce et trouver les sélecteurs
Une fois la page finale en main, l'étape suivante est de localiser chaque champ. Ouvrez la même URL de recherche dans votre navigateur, faites un clic droit sur une carte d'annonce et choisissez Inspecter pour ouvrir les outils de développement. Airbnb enveloppe chaque résultat dans un élément de liste à l'intérieur de la zone de contenu du site, et le titre, la note et le prix se trouvent chacun à des emplacements prévisibles dans cette carte.
D'après le balisage hérité, le conteneur d'annonce et ses champs internes correspondent à ces sélecteurs. Ils constituent un modèle de départ : les noms de classes générés par Airbnb changent, donc réinspectez une page en direct chaque fois qu'un champ revient vide.
-
Conteneur d'annonce :
div#site-content div[itemprop="itemListElement"] -
Titre :
div[data-testid="listing-card-title"] -
Note et avis :
span.r1dxllybà l'intérieur de la carte -
Prix par nuit :
div._i5duul span.a8jt5op -
Lien : le
hrefsur l'ancre de la carte, joint au domaine Airbnb
Étape 3 : parser les champs de l'annonce
Chargez le HTML rendu dans BeautifulSoup, itérez sur chaque conteneur d'annonce et extrayez les champs avec les sélecteurs ci-dessus. Chaque requête est protégée de sorte qu'un champ absent renvoie None au lieu de faire planter l'exécution. Le titre sert aussi de source pour la localisation : Airbnb rédige ses titres de carte sous la forme "Type in Place", donc le texte après "in" est la localisation.
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)]
L'assistant text_of interroge un élément et renvoie son texte nettoyé, ou None si l'élément est absent, de sorte qu'une carte sans un champ ne fait pas planter la boucle. Le sélecteur de note capture la note et le nombre d'avis combinés qu'Airbnb affiche ensemble, par exemple "4.99 (85)". location_from_title lit le lieu depuis le titre de la carte, et amenities_of collecte les courts descripteurs qu'Airbnb affiche dans le sous-titre de la carte. Le href de l'ancre est relatif, donc urljoin le transforme en URL complète. Remarquez ce qui est absent : rien ici ne lit un nom d'hôte, un profil d'hôte ou le texte d'un avis de voyageur. La carte n'expose que des attributs d'annonce publics, et c'est tout ce que le parser collecte.
Les noms de classes générés par Airbnb comme r1dxllyb et a8jt5op changent sans préavis. Traitez les sélecteurs ici comme un modèle de départ, non comme un contrat. Quand un champ revient vide, réinspectez la carte en direct dans les outils de développement de votre navigateur et mettez à jour le sélecteur. La maintenance périodique des sélecteurs est normale pour tout scraper en production, ce n'est pas le signe que quelque chose est cassé.
Étape 4 : gérer la pagination sur les pages de recherche
Une page de recherche est une tranche de l'ensemble des résultats. Airbnb pagine avec un paramètre de requête items_offset, avançant le décalage de la taille de page (18 cartes par page) pour parcourir les résultats. Lisez le décalage pour la page suivante depuis la navigation de pagination quand elle est présente, ou avancez le décalage vous-même jusqu'à un plafond pour qu'un grand marché ne s'emballe pas. Un petit enrouleur de tentative autour de la récupération évite qu'une seule page lente mette fin à l'exécution.
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 tente à nouveau une récupération échouée jusqu'à deux fois avec une courte pause, renvoyant le HTML en cas de succès et None une fois qu'elle abandonne. collect_all_listings parcourt chaque page en avançant items_offset, plafonne le crawl à votre limite max_pages et s'arrête tôt quand une page ne renvoie pas de cartes (la fin naturelle des résultats). Le time.sleep(2) entre les pages cadence l'exécution pour ne pas marteler le site.
Étape 5 : assembler le script complet
Reliez maintenant les pièces en un seul script exécutable : collectez les annonces sur plusieurs pages, puis exportez les enregistrements en JSON et en CSV.
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()
Le script collecte les annonces sur jusqu'à deux pages de recherche, parse chaque carte en un enregistrement et cadence la boucle avec un sleep de deux secondes. save_outputs écrit à la fois un fichier JSON et un CSV ; pour le CSV, il aplatit la liste des équipements en une chaîne séparée par des virgules pour que la colonne reste lisible. Ajustez max_pages et l'URL de recherche en fonction de votre lieu et de vos dates cibles.
À quoi ressemble la sortie
Lancez le script complet avec python airbnb_scraper.py et vous obtenez un enregistrement structuré propre par annonce, prêt pour l'analyse, une base de données ou un tableur. Les titres, notes et prix ci-dessous reflètent la forme qu'Airbnb affiche sur ses cartes.
[ { "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" } ]
Le CSV correspondant porte les mêmes colonnes, une ligne par annonce, que vous pouvez importer directement dans pandas ou n'importe quel tableur pour filtrer par tranche de prix, note ou localisation. Si votre objectif est spécifiquement le suivi des tarifs, le guide complémentaire sur le scraping des prix Airbnb avec Python approfondit le champ prix, et l'intelligence prix par web scraping explique quoi faire des chiffres une fois que vous les avez.
Rester non bloqué à grande échelle
Même avec le rendu géré, Airbnb surveille le trafic aux allures de scraper. Quelques habitudes maintiennent une exécution longue en bonne santé, et elles s'appliquent à toute cible commerciale difficile.
- Cadencez vos requêtes. Marteler les pages de recherche en boucle serrée est le moyen le plus rapide d'être throttlé ou mis en défi. Les sleeps de deux secondes ci-dessus sont le plancher, pas le plafond ; élargissez-les pour les gros travaux et variez vos cibles plutôt que de crawler un seul chemin à pleine vitesse.
- Appuyez-vous sur la rotation. Un pool d'IP résidentielles répartit les requêtes sur de nombreuses adresses de vrais utilisateurs pour qu'aucune ne déclenche de limite de débit. La Crawling API s'en charge pour vous ; si vous construisez votre propre stack, c'est le point à bien régler.
-
Lisez les codes de statut. Une exécution qui commence à renvoyer des valeurs
cb_statusnon-200 vous indique que le débit ou le niveau IP actuel n'est plus suffisant. Traitez ça comme un signal pour ralentir, pas comme du bruit à ignorer.
Pour les crawls plus importants, le Crawler async met en file d'attente les requêtes et livre les résultats vers un webhook, ce qui convient pour traiter de nombreuses pages de recherche sans maintenir des connexions ouvertes. Pour le cadre plus large, voir comment scraper des sites sans se faire bloquer. La même approche à deux couches s'applique aux autres portails d'annonces, comme le scraping d'Apartments.com.
Est-il légal de scraper Airbnb ?
Que le scraping d'Airbnb soit autorisé dépend des conditions d'utilisation d'Airbnb, de votre juridiction et de ce que vous faites des données. Les conditions d'utilisation d'Airbnb restreignent l'accès automatisé, le scraping et la collecte de contenu de la plateforme, 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 fait seulement fonctionner la partie technique. Lisez les conditions d'utilisation d'Airbnb et son fichier robots.txt, respectez les limites de débit qu'ils impliquent, et traitez les deux comme la frontière de ce que vous collectez. Maintenez votre volume de requêtes assez bas pour ne pas surcharger les serveurs d'Airbnb.
La ligne la plus importante est celle des données personnelles. Les annonces Airbnb sont du contenu posté par des utilisateurs, ce qui signifie qu'une page peut contenir des informations sur de vraies personnes : hôtes et voyageurs. Ce guide se limite délibérément aux champs d'annonce publics et non personnels, le titre, le prix par nuit, la note, le nombre d'avis, la localisation, les équipements et le lien vers l'annonce, car c'est la ligne qui rend le travail défendable. Ne collectez pas de noms d'hôtes ou de voyageurs, de photos de profil, de coordonnées ou de toute autre information personnelle, et ne scrapez pas d'avis individuels liés à un voyageur nommé ou ne constituez pas de profils d'hôtes. Ce sont des données personnelles, et là où elles sont impliquées, les lois sur la vie privée comme le RGPD dans l'UE et le CCPA en Californie s'appliquent, avec leurs propres exigences et sanctions. Le caractère public d'un champ ne le rend pas librement collectible quand il identifie une personne.
Pour tout ce qui va au-delà d'un petit échantillon public et non personnel, la bonne voie est un canal officiel plutôt qu'un scraper plus ingénieux. Airbnb dispose de programmes partenaires et d'API pour les intégrations autorisées, et c'est la voie correcte pour un usage commercial ou en volume. En cas de doute sur un cas d'usage spécifique, consultez un juriste avant de construire un produit sur la base de ces données. Le tutoriel technique ci-dessus est un moyen d'apprendre les mécanismes sur des données publiques, pas une licence pour collecter à grande échelle ou toucher quoi que ce soit lié à un individu.
Points clés
- Airbnb est rendu côté client. Une requête simple renvoie une coquille vide avec une grille vide, vous devez donc rendre la page avant de la parser.
-
Vous avez besoin du rendu et d'une IP de confiance ensemble. La Crawling API avec un token JS fait les deux en un seul appel ;
ajax_waitetpage_waitcontrôlent le temps d'attente du contenu. -
Parsez la carte, pas la personne. Itérez les conteneurs
itemListElementet lisez le titre, le prix, la note avec le nombre d'avis, la localisation, les équipements et le lien, tous des champs publics et non personnels. -
Paginez et exportez. Avancez le paramètre
items_offsetd'Airbnb jusqu'à un plafond, cadencez l'exécution avec de courts sleeps, et écrivez les enregistrements en JSON et CSV. - Restez sur les données publiques. Respectez les CGU et le robots.txt d'Airbnb, ne collectez jamais de données personnelles sur les hôtes ou voyageurs ni d'avis nommés, rappelez-vous que le RGPD et le CCPA s'appliquent aux données personnelles, et utilisez l'API officielle ou partenaire d'Airbnb pour la production.
Foire aux questions
Pourquoi une requête simple renvoie-t-elle une grille Airbnb vide ?
Parce qu'Airbnb charge ses résultats de recherche côté client avec JavaScript. Le HTML initial est une coquille qui ne se remplit qu'après l'exécution des scripts de la page dans un navigateur, donc une requête HTTP brute renvoie le statut 200 sans cartes d'annonce. Pour obtenir l'ensemble complet, vous devez d'abord rendre la page, ce que le token JS de la Crawling API gère pour vous.
Ai-je besoin du token normal ou du token JS pour Airbnb ?
Le token JS. Le token normal récupère le HTML statique, qui sur Airbnb est la même coquille vide qu'une requête simple renvoie. Le token JS rend la page dans un vrai navigateur avant de restituer le HTML, de sorte que les cartes d'annonce et leurs champs sont présents quand BeautifulSoup les parse. Les crédits diffèrent pour les requêtes normales et JavaScript, vérifiez votre tableau de bord.
Quels champs puis-je scraper depuis une annonce Airbnb ?
Les champs d'annonce publics et non personnels : le titre de l'annonce, le prix par nuit, la note et le nombre d'avis, la localisation, les principaux équipements et le lien vers l'annonce. Restez sur les données visibles pour tout visiteur sans compte, et ne collectez jamais les noms, profils, coordonnées des hôtes ou voyageurs, ou les avis individuels liés à une personne nommée. Ce sont des données personnelles qui sortent du périmètre des annonces publiques que couvre ce guide.
Mes sélecteurs renvoient None. Qu'est-ce qui a changé ?
Très probablement le balisage d'Airbnb. Ses noms de classes générés (r1dxllyb pour la note, a8jt5op pour le prix, et le test id listing-card-title) changent sans préavis, donc les sélecteurs qui fonctionnaient le mois dernier peuvent casser. Réinspectez une carte en direct dans les outils de développement de votre navigateur et mettez à jour les sélecteurs. La maintenance périodique des sélecteurs est normale pour tout scraper en production.
Comment gérer la pagination sur les annonces d'un lieu ?
Airbnb avance les résultats avec un paramètre de requête items_offset, progressant par pas de 18 cartes. La fonction collect_all_listings ci-dessus incrémente le décalage page par page, plafonne le crawl à un nombre maximum max_pages et s'arrête une fois qu'une page ne renvoie aucune carte. Gardez un court sleep entre les pages pour que l'exécution reste polie.
Puis-je utiliser commercialement les données scrapées d'Airbnb ?
Traitez ça comme une question juridique, pas technique. Les conditions d'utilisation d'Airbnb restreignent le scraping et la réutilisation, et les annonces peuvent contenir des données personnelles couvertes par des lois comme le RGPD et le CCPA, donc l'usage commercial ou en volume nécessite généralement une autorisation. Examinez les conditions, utilisez l'API officielle ou partenaire d'Airbnb pour la production, et consultez un juriste avant de construire un produit sur la base de ces données.
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.
