La semaine dernière, j’ai essayé d’extraire les notes d’hôtels et le nombre d’avis d’environ 200 établissements dans trois villes européennes depuis TripAdvisor. Mon tout premier script — un simple requests.get() avec des en-têtes par défaut — m’a renvoyé un magnifique 403 Forbidden à chaque requête. Pas le moindre octet exploitable.
TripAdvisor est l’une des sources de données publiques les plus riches du secteur du voyage : plus de , plus de 8 millions d’annonces d’entreprises et environ 460 millions de visiteurs mensuels uniques. La plateforme influence plus de de dépenses touristiques par an. Mais récupérer ces données par programme ? C’est là que les choses se compliquent. TripAdvisor s’appuie sur DataDome pour la détection des bots, le WAF Cloudflare, le fingerprinting TLS et des défis JavaScript — une défense en couches qui bloque la plupart des tentatives de scraping naïves avant même qu’elles ne démarrent. Ce guide est la ressource que j’aurais voulu avoir : une comparaison directe de trois approches Python pour scraper (plus une option sans code), le code complet pour chacune, une section structurée de dépannage anti-bot et des patterns réutilisables pour les hôtels, restaurants et attractions. Que vous débutiez en Python ou que vous soyez un développeur expérimenté, cela devrait vous éviter pas mal de 403 pour rien.
Vous ne voulez pas coder ? Scrapez TripAdvisor simplement
Je préfère être clair : beaucoup de personnes qui cherchent "scrape TripAdvisor with Python" ne sont pas forcément attachées à l’idée d’écrire du code. Elles veulent juste les données — noms d’hôtels, notes, nombre d’avis, prix — dans un tableur, et vite. Si c’est votre cas, il existe un chemin bien plus court.
est une extension Chrome dopée à l’IA que nous avons créée. Elle peut lire n’importe quelle page TripAdvisor et proposer automatiquement les bonnes colonnes à extraire. Le workflow tient vraiment en deux clics :
- Ouvrez une page de liste TripAdvisor (par exemple les résultats de recherche "Hotels in Paris").
- Cliquez sur "AI Suggest Fields" dans la barre latérale Thunderbit. L’IA analyse la page et propose des colonnes comme Nom de l’hôtel, Note, Nombre d’avis, Prix et Localisation.
- Cliquez sur "Scrape." Thunderbit extrait les données de chaque fiche de la page — et gère automatiquement la pagination si vous avez besoin de plus de résultats.
- Exportez vers Excel, Google Sheets, Airtable ou Notion. Les exports sont gratuits sur tous les forfaits.
Thunderbit fonctionne sans aucune configuration particulière sur les hôtels, restaurants et attractions — l’IA s’adapte au contenu de la page. Pour les résultats paginés, il détecte automatiquement les boutons "Next" et le scroll infini. Et comme l’outil tourne dans votre vrai navigateur Chrome, il hérite de vos cookies de session et de l’empreinte de votre navigateur, ce qui lui donne un avantage naturel face à la détection des bots.
Vous pouvez l’essayer avec l’ — l’offre gratuite inclut 6 pages/mois, de quoi tester le workflow.
Si vous avez besoin d’un contrôle programmatique, d’une logique d’analyse personnalisée ou que vous prévoyez de scraper plus de 10 000 pages, Python reste la meilleure option. Continuez la lecture.
Pourquoi scraper TripAdvisor avec Python ?
Les données TripAdvisor ont un impact business direct et mesurable. Une a montré qu’une hausse de 1 point du Global Review Index d’un hôtel sur 100 points entraîne une augmentation de 0,89 % du prix journalier moyen et de 1,42 % du Revenue Per Available Room. Une autre a démontré qu’une hausse exogène d’une étoile sur TripAdvisor se traduit par 55 000 à 75 000 dollars de revenus annuels supplémentaires pour un hôtel moyen. Les avis ne sont pas juste des indicateurs de prestige — ce sont de vrais moteurs de revenus.
Voici comment différentes équipes exploitent les données TripAdvisor :
| Cas d’usage | Qui en profite | Données nécessaires |
|---|---|---|
| Analyse concurrentielle hôtelière | Chaînes hôtelières, revenue managers | Notes, prix, volume d’avis, équipements |
| Étude de marché pour la restauration | Groupes de restaurants, marques alimentaires | Types de cuisine, fourchettes de prix, sentiment des avis |
| Suivi des tendances d’attractions | Tour-opérateurs, offices du tourisme | Classements de popularité, tendances saisonnières |
| Analyse de sentiment | Chercheurs, data analysts | Texte complet des avis, notes, dates |
| Génération de leads | Équipes commerciales, agences de voyage | Noms d’entreprises, coordonnées, localisations |
Pourquoi Python en particulier ? Trois raisons. D’abord, l’écosystème : BeautifulSoup, Selenium, Playwright, Scrapy, httpx, pandas — Python dispose de bibliothèques de scraping et d’analyse de données plus matures que n’importe quel autre langage. Ensuite, utilisent Python, ce qui veut dire plus d’aide communautaire, plus de réponses sur StackOverflow et des guides plus à jour. Enfin, l’avantage pipeline : vous pouvez scraper avec BeautifulSoup, nettoyer avec pandas, lancer une analyse de sentiment avec Hugging Face Transformers et construire des tableaux de bord — le tout dans un seul langage. Aucun changement de contexte.
Trois façons de scraper TripAdvisor avec Python (comparées)
La plupart des guides concurrents choisissent une seule méthode et s’y tiennent. Ce n’est pas très utile quand vous devez décider avant d’écrire du code. Voici le tableau comparatif que j’aurais aimé qu’on me donne :
| Approche | Vitesse | Support JS | Résistance anti-bot | Complexité | Idéal pour |
|---|---|---|---|---|---|
requests + BeautifulSoup | ⚡ Rapide (~120–200 pages/min en brut) | ❌ Aucun | ⚠️ Faible | Facile | Pages de listes statiques, petits projets |
| Selenium / navigateur headless | 🐢 Lent (~8–20 pages/min) | ✅ Complet | ⚠️ Moyen | Moyenne | Contenu dynamique, clics "Read more", bannières cookies |
| JSON caché / API GraphQL | ⚡⚡ Le plus rapide (~200–600 pages/min en brut) | N/A | ✅ Plus élevée | Difficile | Extraction à grande échelle d’avis/hôtels |
| Sans code (Thunderbit) | ⚡ Rapide | ✅ Intégré | ✅ Intégré | Le plus simple | Non-développeurs, exports ponctuels rapides |
Quelques précisions importantes. Ces vitesses brutes sont théoriques — les limites de débit de TripAdvisor (~10 à 15 requêtes par minute et par IP) plafonnent le rendement réel à environ 10 pages/minute/IP, quelle que soit l’approche. La méthode JSON caché vous donne le plus de données par requête, ce qui signifie moins de requêtes au total et moins d’exposition au rate limiting. Selenium est 5 fois plus lent que les approches basées sur des requêtes dans les benchmarks réels, mais c’est la seule option quand vous devez cliquer sur des boutons ou rendre du JavaScript.
Le reste de ce guide passe en revue les trois méthodes Python avec le code complet. Choisissez celle qui correspond à votre cas, ou combinez-les (j’utilise souvent requests+BS4 pour les pages de listes et le JSON caché pour les pages détail).
Préparer votre environnement Python
Avant de commencer, mettons l’environnement en place. Vous aurez besoin de Python 3.10+ (je recommande 3.12 ou 3.13 — tous les grands packages les prennent en charge sans problème connu).
Installez tout d’un coup :
1pip install requests beautifulsoup4 selenium httpx parsel pandas curl-cffi
Notes sur les packages :
requests(2.33.1) — requêtes HTTP, nécessite Python 3.10+beautifulsoup4(4.14.3) — parsing HTMLselenium(4.43.0) — automatisation de navigateur, nécessite Python 3.10+httpx(0.28.1) — client HTTP asynchroneparsel(1.11.0) — sélecteurs CSS/XPath (plus léger que BS4)pandas(3.0.2) — export des données, nécessite Python 3.11+curl_cffi(0.15.0) — impersonation de fingerprint TLS (essentiel pour contourner Cloudflare)
ChromeDriver : si vous utilisez Selenium, bonne nouvelle — depuis Selenium 4.6+, Selenium Manager télécharge et met en cache automatiquement le binaire ChromeDriver adapté. Pas d’installation manuelle nécessaire. La compatibilité de version est gérée dynamiquement, donc pas de souci de décalage entre Chrome et le driver.
Environnement virtuel (recommandé) :
1python -m venv tripadvisor-scraper
2source tripadvisor-scraper/bin/activate # macOS/Linux
3tripadvisor-scraper\Scripts\activate # Windows
Approche 1 : scraper TripAdvisor avec Requests et BeautifulSoup
C’est l’approche la plus simple. Elle fonctionne bien pour les pages de listes (résultats de recherche d’hôtels, listes de restaurants) lorsque les données nécessaires sont présentes dans le HTML statique. Pas de navigateur, pas de rendu JavaScript, très peu de ressources consommées.
Comprendre les formats d’URL TripAdvisor
Les URL TripAdvisor suivent des schémas prévisibles selon la catégorie :
- Hôtels :
https://www.tripadvisor.com/Hotels-g{locationId}-{Location_Name}-Hotels.html - Restaurants :
https://www.tripadvisor.com/Restaurants-g{locationId}-{Location_Name}.html - Attractions :
https://www.tripadvisor.com/Attractions-g{locationId}-Activities-{Location_Name}.html
La pagination utilise le paramètre oa (offset anchors), inséré dans l’URL. Chaque page affiche 30 résultats :
- Page 1 : URL de base (sans paramètre
oa) - Page 2 :
Hotels-g187768-oa30-Italy-Hotels.html - Page 3 :
Hotels-g187768-oa60-Italy-Hotels.html
Pour les pages d’avis, le paramètre d’offset est or avec des incréments de 10 :
- Page 1 :
Reviews-or0-Hotel_Name.html - Page 2 :
Reviews-or10-Hotel_Name.html
Pour obtenir les avis dans toutes les langues, ajoutez ?filterLang=ALL à l’URL.
Envoyer des requêtes avec des en-têtes réalistes
TripAdvisor vérifie les en-têtes de manière agressive. Une requête avec les en-têtes Python par défaut est bloquée immédiatement. Il faut imiter un vrai navigateur Chrome :
1import requests
2import time
3import random
4session = requests.Session()
5headers = {
6 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36",
7 "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
8 "Accept-Language": "en-US,en;q=0.9",
9 "Accept-Encoding": "gzip, deflate, br",
10 "Referer": "https://www.tripadvisor.com/",
11 "Sec-Fetch-Dest": "document",
12 "Sec-Fetch-Mode": "navigate",
13 "Sec-Fetch-Site": "none",
14 "Sec-CH-UA": '"Google Chrome";v="135", "Not-A.Brand";v="8", "Chromium";v="135"',
15 "Sec-CH-UA-Mobile": "?0",
16 "Sec-CH-UA-Platform": '"Windows"',
17}
18session.headers.update(headers)
19url = "https://www.tripadvisor.com/Hotels-g187147-Paris_Ile_de_France-Hotels.html"
20response = session.get(url)
21print(f"Status: {response.status_code}")
22print(f"Content length: {len(response.text)} characters")
Point clé : TripAdvisor vérifie la cohérence entre le User-Agent et les en-têtes Client Hints Sec-CH-UA. Si vous vous présentez comme Chrome 135 dans le User-Agent mais que votre Sec-CH-UA indique Chrome 120, vous serez signalé. Rotations d’en-têtes toujours par ensemble complet, jamais un en-tête à la fois.
Analyser les listes avec BeautifulSoup
Une fois la réponse obtenue, extrayez les données avec BeautifulSoup. TripAdvisor utilise des attributs data-automation et data-test-attribute beaucoup plus stables que les noms de classes CSS (qui changent souvent) :
1from bs4 import BeautifulSoup
2soup = BeautifulSoup(response.text, "html.parser")
3# Trouver toutes les cartes d’hôtels
4cards = soup.select('div[data-test-attribute="location-results-card"]')
5hotels = []
6for card in cards:
7 # Nom de l’hôtel
8 title_el = card.select_one('div[data-automation="hotel-card-title"]')
9 name = title_el.get_text(strip=True) if title_el else None
10 # Lien vers la page détail
11 link_el = card.select_one('div[data-automation="hotel-card-title"] a')
12 link = "https://www.tripadvisor.com" + link_el["href"] if link_el else None
13 # Note
14 rating_el = card.select_one('[data-automation="bubbleRatingValue"]')
15 rating = rating_el.get_text(strip=True) if rating_el else None
16 # Nombre d’avis
17 review_el = card.select_one('[data-automation="bubbleReviewCount"]')
18 review_count = review_el.get_text(strip=True).replace(",", "").split()[0] if review_el else None
19 hotels.append({
20 "name": name,
21 "rating": rating,
22 "review_count": review_count,
23 "url": link,
24 })
25print(f"Found {len(hotels)} hotels on this page")
26for h in hotels[:3]:
27 print(h)
À propos des sélecteurs : TripAdvisor utilise des noms de classes CSS obfusqués (comme FGwzt, yyzcQ) qui changent à chaque mise à jour du site. Les attributs data-automation et data-test-target sont bien plus stables. Préférez toujours les attributs de données aux noms de classes.
Gérer la pagination
Pour scraper plusieurs pages, bouclez sur le paramètre d’offset avec une pause polie entre les requêtes :
1import pandas as pd
2all_hotels = []
3base_url = "https://www.tripadvisor.com/Hotels-g187147-oa{offset}-Paris_Ile_de_France-Hotels.html"
4for page in range(5): # 5 premières pages
5 offset = page * 30
6 url = base_url.format(offset=offset) if page > 0 else "https://www.tripadvisor.com/Hotels-g187147-Paris_Ile_de_France-Hotels.html"
7 response = session.get(url)
8 if response.status_code != 200:
9 print(f"Page {page + 1}: status {response.status_code}, arrêt.")
10 break
11 soup = BeautifulSoup(response.text, "html.parser")
12 cards = soup.select('div[data-test-attribute="location-results-card"]')
13 for card in cards:
14 title_el = card.select_one('div[data-automation="hotel-card-title"]')
15 name = title_el.get_text(strip=True) if title_el else None
16 rating_el = card.select_one('[data-automation="bubbleRatingValue"]')
17 rating = rating_el.get_text(strip=True) if rating_el else None
18 review_el = card.select_one('[data-automation="bubbleReviewCount"]')
19 review_count = review_el.get_text(strip=True).replace(",", "").split()[0] if review_el else None
20 all_hotels.append({"name": name, "rating": rating, "review_count": review_count})
21 print(f"Page {page + 1}: {len(cards)} hôtels trouvés")
22 time.sleep(random.uniform(3, 7)) # délai aléatoire pour éviter le rate limiting
23df = pd.DataFrame(all_hotels)
24print(f"\nTotal d’hôtels extraits : {len(df)}")
Le time.sleep(random.uniform(3, 7)) est important. Le seuil de rate limiting de TripAdvisor est d’environ 10 à 15 requêtes par minute et par IP. Aller plus vite déclenche des CAPTCHA ou des erreurs 429.
Limites de cette approche
Quand cette méthode ne suffit-elle plus ? L’approche requests+BS4 échoue quand :
- TripAdvisor fournit du contenu rendu en JavaScript (certaines pages de résultats en dépendent)
- Le texte des avis est tronqué derrière des boutons "Read more"
- Les protections anti-bot montent d’un cran avec des défis JavaScript ou des CAPTCHA
- Vous avez besoin de données qui n’apparaissent qu’après rendu côté client (prix, disponibilité)
Dans ces cas, il faut soit Selenium (Approche 2), soit la méthode JSON caché (Approche 3).
Approche 2 : scraper TripAdvisor avec Selenium (navigateur headless)
Selenium lance un vrai navigateur, ce qui lui permet de rendre JavaScript, cliquer sur des boutons, gérer les bannières de consentement aux cookies et interagir avec du contenu dynamique. Le coût : il est environ et consomme 300 à 500 Mo de RAM par instance de navigateur.
Configurer Selenium avec des réglages anti-détection
Par défaut, Selenium est détectable très facilement. Le fingerprinting de TripAdvisor le repère immédiatement. Il faut désactiver les indicateurs d’automatisation :
1from selenium import webdriver
2from selenium.webdriver.chrome.options import Options
3from selenium.webdriver.common.by import By
4from selenium.webdriver.support.ui import WebDriverWait
5from selenium.webdriver.support import expected_conditions as EC
6options = Options()
7options.add_argument("--headless=new") # Nouveau mode headless (Chrome 112+)
8options.add_argument("--disable-blink-features=AutomationControlled")
9options.add_argument("--window-size=1920,1080")
10options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, comme Gecko) Chrome/135.0.0.0 Safari/537.36")
11options.add_experimental_option("excludeSwitches", ["enable-automation"])
12options.add_experimental_option("useAutomationExtension", False)
13driver = webdriver.Chrome(options=options)
14# Retirer la propriété webdriver de navigator
15driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
16 "source": "Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"
17})
Est-ce suffisant pour TripAdvisor ? Pour du scraping à petite échelle (moins de 50 pages), cette configuration avec des proxies résidentiels fonctionne généralement. Pour des volumes plus importants, vous pourriez avoir besoin de undetected-chromedriver ou nodriver — la protection DataDome de TripAdvisor analyse plus de 1 000 signaux par requête, y compris des fingerprints TLS que Selenium standard ne peut pas usurper.
Scraper les résultats de recherche d’hôtels avec Selenium
1import time
2import random
3url = "https://www.tripadvisor.com/Hotels-g187147-Paris_Ile_de_France-Hotels.html"
4driver.get(url)
5# Attendre le chargement des cartes d’hôtels
6wait = WebDriverWait(driver, 15)
7wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'div[data-test-attribute="location-results-card"]')))
8# Gérer la popup de consentement aux cookies (si elle apparaît)
9try:
10 cookie_btn = driver.find_element(By.ID, "onetrust-accept-btn-handler")
11 cookie_btn.click()
12 time.sleep(1)
13except:
14 pass # Pas de popup cookies
15# Extraire les données des hôtels
16cards = driver.find_elements(By.CSS_SELECTOR, 'div[data-test-attribute="location-results-card"]')
17hotels = []
18for card in cards:
19 try:
20 name = card.find_element(By.CSS_SELECTOR, 'div[data-automation="hotel-card-title"]').text
21 except:
22 name = None
23 try:
24 rating = card.find_element(By.CSS_SELECTOR, '[data-automation="bubbleRatingValue"]').text
25 except:
26 rating = None
27 try:
28 reviews = card.find_element(By.CSS_SELECTOR, '[data-automation="bubbleReviewCount"]').text
29 except:
30 reviews = None
31 hotels.append({"name": name, "rating": rating, "review_count": reviews})
32print(f"Scraped {len(hotels)} hotels")
33for h in hotels[:3]:
34 print(h)
Cela m’a pris environ 8 secondes pour une seule page sur ma machine — contre moins d’une seconde avec requests+BS4. Cet écart de 8x devient vite important lorsqu’on scrape des centaines de pages.
Déployer "Read more" et extraire les avis complets
Les pages d’avis tronquent les longs commentaires derrière un bouton "Read more". Selenium peut cliquer dessus :
1review_url = "https://www.tripadvisor.com/Hotel_Review-g187147-d188726-Reviews-Le_Marais_Hotel-Paris_Ile_de_France.html"
2driver.get(review_url)
3wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'div[data-reviewid]')))
4time.sleep(2)
5# Cliquer sur tous les boutons "Read more"
6read_more_buttons = driver.find_elements(By.XPATH, '//button//*[contains(text(), "Read more")]/..')
7for btn in read_more_buttons:
8 try:
9 driver.execute_script("arguments[0].click();", btn)
10 time.sleep(0.3)
11 except:
12 pass
13# Extraire les avis
14review_elements = driver.find_elements(By.CSS_SELECTOR, 'div[data-reviewid]')
15reviews = []
16for rev in review_elements:
17 try:
18 title = rev.find_element(By.CSS_SELECTOR, 'div[data-test-target="review-title"]').text
19 except:
20 title = None
21 try:
22 body = rev.find_element(By.CSS_SELECTOR, 'q.IRsGHoPm span').text
23 except:
24 try:
25 body = rev.find_element(By.CSS_SELECTOR, 'p.partial_entry').text
26 except:
27 body = None
28 try:
29 rating_class = rev.find_element(By.CSS_SELECTOR, 'div[data-test-target="review-rating"] span').get_attribute("class")
30 # La note est encodée dans une classe du type "ui_bubble_rating bubble_50" = 5.0
31 rating_num = [c for c in rating_class.split() if "bubble_" in c][0].replace("bubble_", "")
32 rating = int(rating_num) / 10
33 except:
34 rating = None
35 reviews.append({"title": title, "body": body, "rating": rating})
36print(f"Scraped {len(reviews)} reviews")
Ajouter de la rotation de proxies à Selenium
Pour un scraping durable, vous aurez besoin de rotation de proxies. Comme selenium-wire est déprécié depuis janvier 2024, utilisez la prise en charge native des proxies par Chrome :
1# Avec un proxy sans authentification
2proxy = "http://your-proxy-address:port"
3options.add_argument(f"--proxy-server={proxy}")
4# Pour les proxies avec authentification, utilisez une extension Chrome ou le protocole BiDi de Selenium 4
Pour faire tourner les proxies par programme, créez une nouvelle instance de driver avec un proxy différent pour chaque lot de requêtes. Ce n’est pas élégant, mais c’est fiable.
Approche 3 : la méthode JSON caché (sans parser le HTML)
La plupart des guides ignorent complètement cette approche, ce qui est dommage — c’est la plus rapide et la plus propre des trois. TripAdvisor intègre des données structurées sous forme de JSON directement dans ses pages HTML — dans des balises <script> sous forme de variables JavaScript comme pageManifest et urqlCache. Extraire ce JSON vous donne des données plus propres (notes numériques, dates au format ISO), avec moins de requêtes et sans rendu JavaScript.
Repérer le JSON embarqué dans le code source
L’idée clé : vous pouvez utiliser un simple requests.get() pour récupérer la page, puis extraire le JSON du HTML brut sans jamais rendre le JavaScript.
1import requests
2import re
3import json
4headers = {
5 "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36",
6 "Accept-Language": "en-US,en;q=0.9",
7 "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
8 "Referer": "https://www.tripadvisor.com/",
9 "Sec-CH-UA": '"Google Chrome";v="135", "Not-A.Brand";v="8", "Chromium";v="135"',
10 "Sec-CH-UA-Mobile": "?0",
11 "Sec-CH-UA-Platform": '"macOS"',
12}
13url = "https://www.tripadvisor.com/Hotel_Review-g188590-d194317-Reviews-NH_City_Centre_Amsterdam.html"
14response = requests.get(url, headers=headers)
15# Extraire le bloc JSON pageManifest
16match = re.search(r"pageManifest:({.+?})};", response.text)
17if match:
18 page_data = json.loads(match.group(1))
19 print("Données pageManifest trouvées")
20 print(f"Clés : {list(page_data.keys())[:10]}")
Comment trouver le nom de la variable vous-même : ouvrez n’importe quelle page d’hôtel TripAdvisor dans Chrome, faites clic droit → Afficher le code source, puis Ctrl+F sur pageManifest, urqlCache ou aggregateRating. Les données sont là, prêtes à être extraites.
Parser le JSON et extraire des données structurées
TripAdvisor embarque aussi des données schema.org application/ld+json, encore plus simples à extraire :
1from parsel import Selector
2sel = Selector(text=response.text)
3# Extraire les données structurées JSON-LD
4json_ld_scripts = sel.xpath("//script[@type='application/ld+json']/text()").getall()
5for script in json_ld_scripts:
6 data = json.loads(script)
7 if isinstance(data, dict) and data.get("@type") in ["Hotel", "Restaurant", "TouristAttraction"]:
8 print(f"Name: {data.get('name')}")
9 print(f"Rating: {data.get('aggregateRating', {}).get('ratingValue')}")
10 print(f"Review Count: {data.get('aggregateRating', {}).get('reviewCount')}")
11 print(f"Price Range: {data.get('priceRange')}")
12 print(f"Address: {data.get('address', {}).get('streetAddress')}")
13 print(f"Coordinates: {data.get('geo', {}).get('latitude')}, {data.get('geo', {}).get('longitude')}")
14 break
Les données JSON-LD sont intégrées dans le HTML statique et ne nécessitent PAS de rendu JavaScript. Elles vous donnent le nom de l’établissement, la note globale, le nombre d’avis, l’adresse, les coordonnées, la gamme de prix et les URL des photos — sans parser une seule balise HTML.
Pour des données plus riches (avis individuels, répartition des notes, listes d’équipements), vous devez utiliser l’objet urqlCache :
1# Extraire urqlCache pour les données détaillées des avis
2cache_match = re.search(r'"urqlCache"\s*:\s*({.+?})\s*,\s*"redux"', response.text)
3if cache_match:
4 cache_data = json.loads(cache_match.group(1))
5 # Parcourir le cache pour trouver les données d’avis
6 for key, value in cache_data.items():
7 if "reviews" in str(value).lower()[:100]:
8 reviews_data = json.loads(value.get("data", "{}")) if isinstance(value, dict) else None
9 if reviews_data:
10 print(f"Entrée de cache avis trouvée : {key[:50]}...")
11 break
Les chemins JSON exacts changent parfois lorsque TripAdvisor met à jour son frontend, mais la structure générale — JSON-LD pour les données de résumé, urqlCache pour les données détaillées — est restée stable pendant des années.
Inverser l’API GraphQL de TripAdvisor (avancé)
Pour l’extraction à grande échelle, les endpoints GraphQL de TripAdvisor renvoient directement des données structurées. C’est la méthode la plus rapide, mais aussi celle qui demande le plus de maintenance.
1import httpx
2import random
3import string
4def generate_request_id():
5 """Génère la valeur de l’en-tête X-Requested-By"""
6 random_chars = ''.join(random.choices(string.ascii_letters + string.digits, k=180))
7 return f"TNI1625!{random_chars}"
8# Rechercher des hôtels à Paris
9search_payload = [{
10 "variables": {
11 "request": {
12 "query": "hotels in Paris",
13 "limit": 10,
14 "scope": "WORLDWIDE",
15 "locale": "en-US",
16 "scopeGeoId": 1,
17 "searchCenter": None,
18 "types": ["LOCATION", "QUERY_SUGGESTION", "RESCUE_RESULT"],
19 "locationTypes": ["GEO", "AIRPORT", "ACCOMMODATION", "ATTRACTION", "EATERY", "NEIGHBORHOOD"]
20 }
21 },
22 "extensions": {
23 "preRegisteredQueryId": "84b17ed122fbdbd4"
24 }
25}]
26graphql_headers = {
27 "Content-Type": "application/json",
28 "Accept": "*/*",
29 "Accept-Language": "en-US,en;q=0.9",
30 "Origin": "https://www.tripadvisor.com",
31 "Referer": "https://www.tripadvisor.com/Hotels",
32 "X-Requested-By": generate_request_id(),
33 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, comme Gecko) Chrome/135.0.0.0 Safari/537.36",
34}
35with httpx.Client() as client:
36 response = client.post(
37 "https://www.tripadvisor.com/data/graphql/ids",
38 json=search_payload,
39 headers=graphql_headers
40 )
41 if response.status_code == 200:
42 results = response.json()
43 print(json.dumps(results, indent=2)[:1000])
44 else:
45 print(f"GraphQL request failed: {response.status_code}")
Pour récupérer les avis via GraphQL :
1review_payload = [{
2 "variables": {
3 "locationId": 194317, # NH City Centre Amsterdam
4 "offset": 0,
5 "limit": 20,
6 "filters": {},
7 "sortType": None,
8 "sortBy": "date",
9 "language": "en",
10 "doMachineTranslation": False,
11 "photosPerReviewLimit": 3
12 },
13 "extensions": {
14 "preRegisteredQueryId": "ef1a9f94012220d3"
15 }
16}]
17with httpx.Client() as client:
18 response = client.post(
19 "https://www.tripadvisor.com/data/graphql/ids",
20 json=review_payload,
21 headers=graphql_headers
22 )
23 if response.status_code == 200:
24 data = response.json()
25 reviews = data[0]["data"]["locations"][0]["reviewListPage"]["reviews"]
26 total = data[0]["data"]["locations"][0]["reviewListPage"]["totalCount"]
27 print(f"Total reviews: {total}")
28 for r in reviews[:3]:
29 print(f" [{r['rating']}/5] {r['title']} - {r['createdDate']}")
Point important : les valeurs preRegisteredQueryId (comme 84b17ed122fbdbd4 pour la recherche et ef1a9f94012220d3 pour les avis) peuvent casser lorsque TripAdvisor redéploie. Quand cela arrive, vos requêtes échouent silencieusement. Il faudra redécouvrir les identifiants de requête en surveillant le trafic réseau dans les DevTools du navigateur.
Pourquoi cette méthode réduit le besoin en proxies
Le calcul est simple. Avec requests+BS4, scraper 100 pages détail d’hôtels nécessite 100 requêtes. Avec la méthode JSON caché, chaque requête renvoie toutes les données nécessaires d’un seul chargement de page — pas besoin de requêtes supplémentaires pour dérouler les avis ou charger le contenu dynamique. Avec GraphQL, une seule requête API peut renvoyer 20 avis d’un coup. Moins de requêtes = moins d’exposition au rate limiting = moins de besoin de rotation de proxies. Pour les projets de petite à moyenne taille (moins de 1 000 pages), vous n’aurez peut-être même pas besoin de proxies si vous ajoutez des délais raisonnables.
Scraper hôtels, restaurants et attractions avec un seul script réutilisable
Quatre guides concurrents sur cinq ne couvrent que les hôtels. Mais TripAdvisor a trois grandes catégories de contenu, et les schémas d’URL ainsi que les champs disponibles diffèrent entre elles. Voici comment créer une fonction unique qui gère les trois.
Champs disponibles par catégorie
| Champ | Hôtels | Restaurants | Attractions |
|---|---|---|---|
| Nom | ✅ | ✅ | ✅ |
| Note | ✅ | ✅ | ✅ |
| Nombre d’avis | ✅ | ✅ | ✅ |
| Prix / fourchette de prix | ✅ | ✅ | Parfois |
| Adresse | ✅ | ✅ | ✅ |
| Type de cuisine | ❌ | ✅ | ❌ |
| Durée / type de visite | ❌ | ❌ | ✅ |
| Équipements | ✅ | ❌ | ❌ |
| Coordonnées | ✅ | ✅ | ✅ |
Construire une fonction scrape_tripadvisor() réutilisable
1import requests
2from bs4 import BeautifulSoup
3import pandas as pd
4import time
5import random
6import re
7import json
8def scrape_tripadvisor(category, location_id, location_name, num_pages=3):
9 """
10 Scraper les listes TripAdvisor pour les hôtels, restaurants ou attractions.
11 Args:
12 category: "hotels", "restaurants" ou "attractions"
13 location_id: ID géographique TripAdvisor (ex. "187147" pour Paris)
14 location_name: nom compatible URL (ex. "Paris_Ile_de_France")
15 num_pages: nombre de pages à scraper
16 """
17 url_patterns = {
18 "hotels": "https://www.tripadvisor.com/Hotels-g{geo}-oa{offset}-{name}-Hotels.html",
19 "restaurants": "https://www.tripadvisor.com/Restaurants-g{geo}-oa{offset}-{name}.html",
20 "attractions": "https://www.tripadvisor.com/Attractions-g{geo}-oa{offset}-Activities-{name}.html",
21 }
22 first_page_patterns = {
23 "hotels": "https://www.tripadvisor.com/Hotels-g{geo}-{name}-Hotels.html",
24 "restaurants": "https://www.tripadvisor.com/Restaurants-g{geo}-{name}.html",
25 "attractions": "https://www.tripadvisor.com/Attractions-g{geo}-Activities-{name}.html",
26 }
27 headers = {
28 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, comme Gecko) Chrome/135.0.0.0 Safari/537.36",
29 "Accept-Language": "en-US,en;q=0.9",
30 "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
31 "Referer": "https://www.tripadvisor.com/",
32 "Sec-CH-UA": '"Google Chrome";v="135", "Not-A.Brand";v="8", "Chromium";v="135"',
33 "Sec-CH-UA-Mobile": "?0",
34 "Sec-CH-UA-Platform": '"Windows"',
35 }
36 session = requests.Session()
37 session.headers.update(headers)
38 all_items = []
39 for page in range(num_pages):
40 offset = page * 30
41 if page == 0:
42 url = first_page_patterns[category].format(geo=location_id, name=location_name)
43 else:
44 url = url_patterns[category].format(geo=location_id, offset=offset, name=location_name)
45 response = session.get(url)
46 if response.status_code != 200:
47 print(f" Page {page + 1}: status {response.status_code}, arrêt.")
48 break
49 soup = BeautifulSoup(response.text, "html.parser")
50 cards = soup.select('div[data-test-attribute="location-results-card"]')
51 for card in cards:
52 item = {"category": category}
53 title_el = card.select_one('div[data-automation="hotel-card-title"]') or card.select_one('a[data-automation]')
54 item["name"] = title_el.get_text(strip=True) if title_el else None
55 rating_el = card.select_one('[data-automation="bubbleRatingValue"]')
56 item["rating"] = rating_el.get_text(strip=True) if rating_el else None
57 review_el = card.select_one('[data-automation="bubbleReviewCount"]')
58 item["review_count"] = review_el.get_text(strip=True) if review_el else None
59 all_items.append(item)
60 print(f" Page {page + 1}: {len(cards)} éléments trouvés")
61 time.sleep(random.uniform(3, 7))
62 return pd.DataFrame(all_items)
63# Exemples d’utilisation
64print("=== Hôtels à Paris ===")
65hotels_df = scrape_tripadvisor("hotels", "187147", "Paris_Ile_de_France", num_pages=2)
66print(hotels_df.head())
67print("\n=== Restaurants à Rome ===")
68restaurants_df = scrape_tripadvisor("restaurants", "187791", "Rome_Lazio", num_pages=2)
69print(restaurants_df.head())
70print("\n=== Attractions à Barcelone ===")
71attractions_df = scrape_tripadvisor("attractions", "187497", "Barcelona_Catalonia", num_pages=2)
72print(attractions_df.head())
Une seule fonction, trois catégories, zéro duplication de code. Si TripAdvisor change un sélecteur, vous le corrigez à un seul endroit.
Que faire quand TripAdvisor vous bloque ? (Dépannage anti-bot)
C’est la section dont j’avais le plus besoin quand j’ai commencé à scraper TripAdvisor, et c’est aussi celle qu’aucun guide concurrent ne présente de façon structurée. TripAdvisor combine DataDome (qui analyse par jour) et le WAF Cloudflare. Voici un tableau de diagnostic pour les échecs les plus courants :
| Symptôme | Cause probable | Solution |
|---|---|---|
| Réponse HTTP 403 | En-têtes manquants ou suspects ; défi JavaScript Cloudflare | Définissez des en-têtes réalistes User-Agent, Accept-Language, Referer et Sec-CH-UA. Assurez-vous qu’ils sont cohérents. |
| Page CAPTCHA au lieu des données | Rate limiting ou fingerprinting du navigateur | Faites tourner des proxies résidentiels, ajoutez des délais aléatoires (2 à 7 secondes entre les requêtes) |
| HTML vide ou corps de page vide | JavaScript non rendu par requests | Passez à Selenium ou extrayez depuis le JSON caché dans le code source |
| Avis partiels / "Read more" qui ne s’ouvre pas | Contenu chargé sur événement de clic | Utilisez le .click() de Selenium ou extrayez depuis le blob JSON embarqué |
| Avis dans une seule langue | Paramètre de langue manquant | Ajoutez ?filterLang=ALL à l’URL des avis |
| Les données cessent de se charger après N pages | Limitation basée sur la session | Faites tourner les sessions, videz les cookies entre les lots |
| HTTP 1020 Access Denied | IP/ASN banni par Cloudflare | Passez de proxies datacenter à des proxies résidentiels |
| Boucle de défi (CAPTCHA infini) | Persistance des cookies cassée | Amorcez la session en visitant d’abord la page d’accueil ; conservez le cookie jar |
Logique de retry avec backoff exponentiel
Aucun article concurrent ne montre vraiment ce code. Voici une fonction de retry réutilisable :
1import time
2import random
3import requests
4def fetch_with_retry(session, url, max_retries=4, base_delay=2, max_delay=60):
5 """
6 Récupère une URL avec backoff exponentiel et jitter.
7 Fait tourner le User-Agent à chaque tentative.
8 """
9 user_agents = [
10 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36",
11 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36",
12 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, comme Gecko) Chrome/134.0.0.0 Safari/537.36",
13 "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, comme Gecko) Chrome/135.0.0.0 Safari/537.36",
14 ]
15 for attempt in range(max_retries):
16 # Faire tourner le User-Agent lors des retries
17 if attempt > 0:
18 session.headers["User-Agent"] = random.choice(user_agents)
19 try:
20 response = session.get(url, timeout=30)
21 if response.status_code == 200:
22 return response
23 if response.status_code == 429:
24 # Respecter l’en-tête Retry-After s’il existe
25 retry_after = int(response.headers.get("Retry-After", base_delay * (2 ** attempt)))
26 print(f" Rate limited (429). Attente {retry_after}s...")
27 time.sleep(retry_after)
28 continue
29 if response.status_code in (403, 503):
30 wait = min(base_delay * (2 ** attempt) + random.uniform(0, 1), max_delay)
31 print(f" Code {response.status_code}. Retry {attempt + 1}/{max_retries} dans {wait:.1f}s...")
32 time.sleep(wait)
33 continue
34 # Autres codes d’erreur — ne pas retenter
35 print(f" Statut inattendu {response.status_code} pour {url}")
36 return response
37 except requests.exceptions.Timeout:
38 wait = min(base_delay * (2 ** attempt) + random.uniform(0, 1), max_delay)
39 print(f" Timeout. Retry {attempt + 1}/{max_retries} dans {wait:.1f}s...")
40 time.sleep(wait)
41 print(f" Tous les retries ({max_retries}) sont épuisés pour {url}")
42 return None
Rotation des en-têtes, proxies et sessions
Pour un scraping soutenu, maintenez un pool d’en-têtes et faites-les tourner ensemble :
1import random
2HEADER_SETS = [
3 {
4 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36",
5 "Sec-CH-UA": '"Google Chrome";v="135", "Not-A.Brand";v="8", "Chromium";v="135"',
6 "Sec-CH-UA-Platform": '"Windows"',
7 },
8 {
9 "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36",
10 "Sec-CH-UA": '"Google Chrome";v="135", "Not-A.Brand";v="8", "Chromium";v="135"',
11 "Sec-CH-UA-Platform": '"macOS"',
12 },
13 {
14 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36",
15 "Sec-CH-UA": '"Google Chrome";v="134", "Not-A.Brand";v="8", "Chromium";v="134"',
16 "Sec-CH-UA-Platform": '"Windows"',
17 },
18]
19PROXY_LIST = [
20 "http://user:pass@residential-proxy-1:port",
21 "http://user:pass@residential-proxy-2:port",
22 # Ajoutez d’autres proxies résidentiels
23]
24def get_rotated_session():
25 """Crée une nouvelle session avec des en-têtes et un proxy tournants."""
26 session = requests.Session()
27 # Choisir un ensemble d’en-têtes au hasard
28 header_set = random.choice(HEADER_SETS)
29 base_headers = {
30 "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
31 "Accept-Language": "en-US,en;q=0.9",
32 "Accept-Encoding": "gzip, deflate, br",
33 "Referer": "https://www.tripadvisor.com/",
34 "Sec-Fetch-Dest": "document",
35 "Sec-Fetch-Mode": "navigate",
36 "Sec-CH-UA-Mobile": "?0",
37 }
38 base_headers.update(header_set)
39 session.headers.update(base_headers)
40 # Choisir un proxy au hasard
41 if PROXY_LIST:
42 proxy = random.choice(PROXY_LIST)
43 session.proxies = {"http": proxy, "https": proxy}
44 return session
Le type de proxy compte. Les proxies datacenter sont bloqués presque immédiatement par TripAdvisor (HTTP 1020 Access Denied). Les proxies résidentiels sont indispensables pour un scraping durable — ils passent par des FAI grand public et sont indiscernables d’utilisateurs réels. Comptez entre 2,50 $ et 8,40 $/Go selon le fournisseur.
Exporter et stocker vos données TripAdvisor extraites
Une fois les données récupérées, les mettre dans un format exploitable est simple.
Export CSV (le plus courant)
1import pandas as pd
2df = pd.DataFrame(all_hotels)
3df.to_csv("tripadvisor_hotels_paris.csv", index=False, encoding="utf-8-sig")
4print(f"Exported {len(df)} rows to CSV")
L’encoding='utf-8-sig' est important — il permet à Excel d’afficher correctement les caractères non latins (accents français, caractères chinois, etc.) à l’ouverture du CSV.
Export JSON (pour les données imbriquées)
Quand vous avez des avis imbriqués sous les hôtels, JSON préserve la hiérarchie :
1# Structure hiérarchique
2hotel_data = {
3 "property_id": "d194317",
4 "name": "NH City Centre Amsterdam",
5 "rating": 4.0,
6 "reviews": [
7 {"title": "Great location", "rating": 5, "date": "2025-03-15", "text": "..."},
8 {"title": "Average stay", "rating": 3, "date": "2025-03-10", "text": "..."},
9 ]
10}
11# Pour une analyse plate, utilisez json_normalize
12flat_reviews = pd.json_normalize(
13 hotel_data,
14 record_path="reviews",
15 meta=["property_id", "name"]
16)
17flat_reviews.to_csv("reviews_flat.csv", index=False)
Approche en deux fichiers pour les données relationnelles
Pour les grands volumes, j’utilise deux fichiers CSV :
hotels.csv— une ligne par établissement (plat)reviews.csv— une ligne par avis, avecproperty_idcomme clé étrangère
C’est très pratique pour faire des jointures dans pandas, charger les données dans une base ou les importer dans des outils BI.
Si vous ne voulez pas gérer toute cette logique d’export, Thunderbit vous permet d’ vers Excel, Google Sheets, Airtable ou Notion — le tout gratuitement, sans code. Très pratique quand vous devez partager les résultats avec des collègues non techniques.
Conseils pour un scraping TripAdvisor responsable et efficace
Un scraping responsable en six points :
- Vérifiez
robots.txt: lerobots.txtde TripAdvisor bloque entièrement les bots d’entraînement IA (GPTBot, ClaudeBot, etc.). Les crawlers standards font face à des restrictions de chemins ciblées. Consulteztripadvisor.com/robots.txt. - Ajoutez des pauses : 3 à 7 secondes entre les requêtes est une plage sûre. Aller plus vite que 10 à 15 requêtes par minute et par IP déclenche le rate limiting.
- Ne scrapez que des données publiques. Ne vous connectez pas pour accéder à du contenu restreint.
- Stockez les données de façon sécurisée et respectez le RGPD / CCPA si vous traitez des informations personnelles (noms des contributeurs, etc.).
- Envisagez l’API officielle de TripAdvisor si vous avez besoin de données à l’échelle commerciale. Le donne accès aux informations d’entreprise, ainsi qu’à 5 avis et 5 photos par emplacement — limité, mais légal et stable.
- Tenez compte du contexte juridique : l’ a renforcé les restrictions de scraping fondées sur les CGU dans l’Union européenne. Les conditions d’utilisation de TripAdvisor interdisent explicitement le scraping. Faites-le de manière responsable et à vos risques et périls.
Conclusion
Voilà la vue d’ensemble complète.
- Requests + BeautifulSoup est la voie la plus simple. Cette méthode fonctionne pour les pages de listes statiques, demande une configuration minimale et va vite. Commencez par là si vous scrapez moins de 100 pages et que vous n’avez pas besoin de contenu rendu en JavaScript.
- Selenium gère tout ce que requests ne sait pas faire : contenu dynamique, boutons "Read more", bannières de cookies. C’est 5 fois plus lent et gourmand en ressources, mais c’est la seule option quand il faut interagir avec la page.
- JSON caché / GraphQL est l’approche la plus propre et la plus rapide. Elle fournit des données structurées sans parser le HTML, réduit le nombre de requêtes (et donc le besoin en proxies) et renvoie des données directement exploitables. En revanche, elle demande un peu plus de rétro-ingénierie au départ et parfois de la maintenance quand TripAdvisor change sa structure de données.
La fonction réutilisable scrape_tripadvisor() couvre les hôtels, restaurants et attractions. Vous ne devriez pas avoir besoin d’un deuxième tutoriel.
Et si, au milieu du guide, vous décidez que coder n’est pas pour vous — ou que vous avez simplement besoin de 50 hôtels dans un tableur avant la fin de la journée — le fait en deux clics avec détection de champs assistée par IA, pagination automatique et export gratuit vers Excel ou Google Sheets. Aucun Python requis.
Si vous voulez aller plus loin, nous avons d’autres guides de scraping sur le et notre .
FAQ
1. Est-il légal de scraper TripAdvisor ?
Les Conditions d’utilisation de TripAdvisor interdisent explicitement le scraping. Cela dit, les tribunaux ont généralement estimé que le scraping de données publiquement accessibles (sans connexion) ne viole pas le Computer Fraud and Abuse Act aux États-Unis. En revanche, l’arrêt Ryanair de la Cour de l’UE en 2025 a renforcé les restrictions basées sur les CGU en Europe. Ne scrapez que des données publiques, respectez robots.txt, ne republiez pas de contenu protégé par le droit d’auteur et consultez un juriste si vous utilisez ces données à des fins commerciales.
2. Puis-je scraper TripAdvisor sans Python ?
Oui. Des outils sans code comme peuvent scraper TripAdvisor directement depuis votre navigateur avec détection de champs par IA et pagination automatique. Vous pouvez aussi utiliser des extensions de navigateur, des add-ons Google Sheets ou des API de scraping commerciales. Python offre le plus de contrôle et de flexibilité, mais ce n’est pas la seule option.
3. Comment éviter d’être bloqué en scrapant TripAdvisor ?
Les tactiques clés : utilisez des en-têtes réalistes et cohérents (surtout User-Agent et Sec-CH-UA), faites tourner des proxies résidentiels (les IP datacenter sont bloquées immédiatement), ajoutez des délais aléatoires de 3 à 7 secondes entre les requêtes, utilisez la méthode JSON caché pour réduire le nombre total de requêtes, mettez en place une logique de retry avec backoff exponentiel et amorcez les sessions en visitant la page d’accueil avant de scraper des pages profondes.
4. Quelles données puis-je extraire de TripAdvisor ?
Des hôtels, restaurants et attractions — y compris les noms, notes, nombre d’avis, fourchettes de prix, adresses, coordonnées, équipements (hôtels), types de cuisine (restaurants), durées de visite (attractions) et le texte complet des avis avec notes individuelles et dates. Les approches JSON caché et GraphQL fournissent les données les plus riches par requête.
5. Combien de pages puis-je scraper par jour sur TripAdvisor ?
Avec une seule IP et des délais raisonnables : environ 600 à 1 000 pages par jour. Avec 20 proxies résidentiels en rotation : environ 200 000 à 300 000 pages par jour avec des approches basées sur des requêtes. Selenium est plus lent — attendez-vous à 8 000 à 12 000 pages par jour et par proxy. L’approche JSON caché / GraphQL vous donne le plus de données par requête, donc vous pourriez avoir besoin de beaucoup moins de pages au total pour obtenir la même quantité d’informations.
En savoir plus
