Ważne zastrzeżenie prawne: Ten artykuł dotyczy wyłącznie dostępu do publicznie dostępnych danych, w sposób zgodny z Regulaminem TripAdvisor (Terms of Use) oraz obowiązującym prawem — w tym CFAA w USA i RODO w UE. Nie zachęcamy do omijania zabezpieczeń technicznych, zbierania danych osobowych ani naruszania warunków korzystania z usług. Jeśli TripAdvisor oferuje oficjalne API dla Twojego przypadku użycia, użyj go w pierwszej kolejności.
TripAdvisor to jedno z najbogatszych źródeł publicznych opinii o hotelach i restauracjach — setki milionów recenzji na stronach typu /Hotel_Review i /Restaurant_Review. Dla zespołów zajmujących się analizą rynku podróży, monitorowaniem reputacji i badaniem konkurencji, scrapowanie TripAdvisor to realna potrzeba. Problem w tym, że strona aktywnie blokuje automatyczny ruch, a naiwne podejścia z requests i datacenter IP kończą się błędem 403 po kilku zapytaniach.
W tym przewodniku pokazujemy, jak ekstrahować dane TripAdvisor w 2026 roku — od zrozumienia architektury strony, przez GraphQL endpoint, po konfigurację proxy rezydencjalnych z ProxyHat. Skupiamy się na danych publicznych: tytułach, ocenach, treści opinii i datach publikacji.
Jak scrapować opinie TripAdvisor w 2026 — podsumowanie podejścia
Krótko: TripAdvisor lazy-loaduje opinie przez wewnętrzny endpoint GraphQL (/data/graphql/ids, POST), chroniony przez Cloudflare i DataDome. Datacenter IP są blokowane niezależnie od nagłówków, dlatego wymagane są rotujące proxy rezydencjalne z geo-targetowaniem kraju/miasta. Do żądań używamy biblioteki curl_cffi, która impersonifikuje fingerprint TLS przeglądarki Chrome. Realistyczny limit to około 50–100 listingów na godzinę per IP, z backoff i sesjami sticky.
Co jest publiczne na TripAdvisor
Strony /Hotel_Review i /Restaurant_Review publicznie wyświetlają:
- Nazwę obiektu, adres, kategorię, ogólny rating (1–5 gwiazdek).
- Poszczególne opinie: tytuł, tekst, data publikacji, ocena, nazwa użytkownika (pseudonim).
- Podsumowania ocen (liczba opinii na każdą gwiazdkę).
Opinie nie są jednak w statycznym HTML-u. TripAdvisor stosuje lazy-loading — początkowy HTML zawiera tylko kilka recenzji lub ich placeholder, a reszta jest doczytywana asynchronicznie przez JavaScript. Dlatego zwykły requests.get() zwraca pustą lub niekompletną stronę. Można to obejść na dwa sposoby:
- Renderowanie przeglądarki (Playwright/Selenium) — wolne, drogie, podatne na detekcję.
- Bezpośrednie wywołanie GraphQL endpoint — szybkie, zwraca ustrukturyzowany JSON, ale wymaga poprawnego fingerprintu TLS i tokena.
Polecamy drugie podejście. Jest znacznie wydajniejsze i bardziej niezawodne, jeśli odpowiednio skonfigurujesz proxy.
Stack anty-bot TripAdvisor
TripAdvisor chroni swoją infrastrukturę wielowarstwowo. Zrozumienie tych warstw jest kluczowe, by TripAdvisor review scraper działał stabilnie.
Cloudflare i DataDome
Na poziomie CDN TripAdvisor korzysta z Cloudflare, a warstwę anti-bot uzupełnia DataDome — system analizujący sygnatury TLS, nagłówki HTTP, zachowanie sesji i reputację IP. DataDome jest szczególnie agresywny wobec ruchu z datacenter IP. Według dokumentacji DataDome, ich silnik analizuje ponad 50 sygnałów w czasie rzeczywistym, w tym JA3/JA4 fingerprint TLS, kolejność nagłówków HTTP/2 i parametry ClientHello.
Fingerprinting TLS/HTTP2
Nawet jeśli ustawisz idealne nagłówki przeglądarki (User-Agent, Accept-Language, Sec-CH-UA), biblioteki takie jak requests czy standardowy httpx mają charakterystyczny fingerprint TLS różniący się od Chrome. DataDome to wykrywa i blokuje. Rozwiązaniem jest curl_cffi — wrapper wokół libcurl-impersonate, który replikuje ClientHello i ustawienia HTTP/2 przeglądarki Chrome lub Firefox.
Dlaczego datacenter IP nie działają
Niezależnie od nagłówków i fingerprintu TLS, ruch z zakresów IP należących do AWS, Google Cloud, DigitalOcean czy OVH jest klasyfikowany jako podejrzany. DataDome utrzymuje bazy ASN dla datacenter i blokuje je domyślnie. Dlatego proxy rezydencjalne są wymagane — pochodzą od dostawców ISP, mają realną historię ruchu i są trudne do odróżnienia od organicznych użytkowników.
Wewnętrzny endpoint GraphQL TripAdvisor
TripAdvisor używa GraphQL do lazy-loading opinii. Endpoint to https://www.tripadvisor.com/data/graphql/ids, metoda POST. Wymaga nagłówka X-Requested-By z tokenem, który znajduje się w początkowym HTML (często w obiekcie window.__WEB_CONTEXT__ lub w tagu <meta>). Typowa struktura żądania:
POST /data/graphql/ids HTTP/2
Host: www.tripadvisor.com
Content-Type: application/json
X-Requested-By: <token_z_html>
Cookie: <cookies_z_inicjalnego_get>
[
{
"query": "query ReviewList($locationId: Int!, $offset: Int, $limit: Int) { locationReviews(locationId: $locationId, offset: $offset, limit: $limit) { reviewList { review { title rating text publishedDate } } } }",
"variables": { "locationId": 123456, "offset": 0, "limit": 10 }
}
]
Endpoint przyjmuje tablicę zapytań (batching). Odpowiedź to ustrukturyzowany JSON z węzłami opinii — tytuł, ocena (1–5), tekst (często obcięty do ~200 znaków w darmowej wersji), data publikacji. Paginacja odbywa się przez parametr offset.
Wskazówka: Token X-Requested-By jest powiązany z sesją/cookie. Jeśli zmienisz IP w środku sesji bez zachowania cookie, token może zostać unieważniony. Używaj sesji sticky, aby IP i cookie były spójne.
Lokalizacja i geo-targetowanie
Opinie i listingi TripAdvisor różnią się w zależności od regionu. Jeśli scrapujesz opinie hoteli w Londynie, najlepiej użyć IP z UK — wtedy treść i rankingi są spójne z tym, co widzi lokalny użytkownik. ProxyHat pozwala na geo-targetowanie na poziomie kraju i miasta:
http://user-country-GB-city-london:PASSWORD@gate.proxyhat.com:8080
Sprawdź dostępne lokalizacje na stronie /pl/locations.
Konfiguracja ProxyHat dla scrapowania TripAdvisor
ProxyHat oferuje proxy rezydencjalne, mobilne i datacenter. Do TripAdvisor używaj rezydencjalnych. Konfiguracja:
| Parametr | Wartość |
|---|---|
| Gateway | gate.proxyhat.com |
| Port HTTP | 8080 |
| Port SOCKS5 | 1080 |
| Format URL | http://USERNAME:PASSWORD@gate.proxyhat.com:8080 |
| Geo (kraj) | user-country-GB:pass |
| Geo (miasto) | user-country-GB-city-london:pass |
| Sesja sticky | user-session-abc123:pass |
Szczegóły planów i cen znajdziesz na /pl/pricing. Pełną dokumentację API ProxyHat znajdziesz w docs.proxyhat.com.
Praktyczny przykład w Pythonie
Poniższy przykład używa curl_cffi do impersonifikacji Chrome TLS, proxy rezydencjalnego ProxyHat z geo UK, i wysyła zapytanie GraphQL do TripAdvisor. Kod pobiera token z początkowego HTML, a następnie odpytuje endpoint GraphQL.
import re
import json
from curl_cffi import requests
# Proxy rezydencjalny ProxyHat z geo UK + sticky session
PROXY = "http://user-country-GB-session-trip001:PASSWORD@gate.proxyhat.com:8080"
LOCATION_ID = 658828 # przykładowy hotel w Londynie
BASE = "https://www.tripadvisor.com"
session = requests.Session(impersonate="chrome")
session.proxies = {"http": PROXY, "https": PROXY}
# 1. Pobierz stronę listing, aby uzyskać token i cookies
review_url = f"{BASE}/Hotel_Review-g186338-d{LOCATION_ID}-Reviews.html"
resp = session.get(review_url, timeout=30)
if resp.status_code != 200:
print(f"Błąd początkowy: {resp.status_code}")
exit(1)
html = resp.text
# 2. Wyodrębnij token X-Requested-By
m = re.search(r'"X-Requested-By"\s*:\s*"([^"]+)"', html)
if not m:
m = re.search(r'xRequestedBy["\']?\s*[:=]\s*["\']([^"\']+)', html)
token = m.group(1) if m else None
if not token:
print("Nie znaleziono tokena X-Requested-By")
exit(1)
# 3. Wyślij zapytanie GraphQL
graphql_query = """
query ReviewList($locationId: Int!, $offset: Int, $limit: Int) {
locationReviews(locationId: $locationId, offset: $offset, limit: $limit) {
reviewList {
review {
title
rating
text
publishedDate
}
}
}
}
"""
payload = [{
"query": graphql_query,
"variables": {"locationId": LOCATION_ID, "offset": 0, "limit": 10}
}]
headers = {
"Content-Type": "application/json",
"X-Requested-By": token,
"Referer": review_url,
"Origin": BASE,
}
gql_resp = session.post(
f"{BASE}/data/graphql/ids",
headers=headers,
data=json.dumps(payload),
timeout=30,
)
if gql_resp.status_code == 200:
data = gql_resp.json()
reviews = data[0]["data"]["locationReviews"]["reviewList"]["review"]
for r in reviews[:3]:
print(f"Tytuł: {r.get('title', '')}")
print(f"Ocena: {r.get('rating', '')}/5")
print(f"Data: {r.get('publishedDate', '')}")
print(f"Tekst: {r.get('text', '')[:200]}...")
print("---")
else:
print(f"Błąd GraphQL: {gql_resp.status_code}")
Ten kod pobiera pierwsze 10 opinii dla danego locationId. Paginacja odbywa się przez zmianę offset — np. 0, 10, 20, 30.
Przykład w Node.js (opcjonalnie)
const { Curl } = require('node-libcurl');
const proxy = 'http://user-country-GB-session-trip002:PASSWORD@gate.proxyhat.com:8080';
const locationId = 658828;
const base = 'https://www.tripadvisor.com';
const curl = new Curl();
curl.setOpt('URL', `${base}/data/graphql/ids`);
curl.setOpt('PROXY', proxy);
curl.setOpt('HTTPHEADER', [
'Content-Type: application/json',
'X-Requested-By: TOKEN_HERE',
`Referer: ${base}/Hotel_Review-g186338-d${locationId}-Reviews.html`,
]);
curl.setOpt('POSTFIELDS', JSON.stringify([{
query: 'query ReviewList($locationId: Int!, $offset: Int, $limit: Int) { locationReviews(locationId: $locationId, offset: $offset, limit: $limit) { reviewList { review { title rating text publishedDate } } } }',
variables: { locationId, offset: 0, limit: 10 },
}]));
curl.setOpt('SSL_VERIFYPEER', false);
curl.on('end', (status, body) => {
console.log('Status:', status);
console.log('Body:', body.substring(0, 500));
});
curl.perform();
Realistyczne limity i strategia rotacji
TripAdvisor nie publikuje oficjalnych limitów dla nieautoryzowanego ruchu, ale z doświadczenia wynika, że:
- Bez proxy: 5–15 zapytań, potem 403 lub challenge DataDome.
- Z jednym IP rezydencjalnym: około 50–100 listingów na godzinę, potem tymczasowy soft-block (zwykle 5–10 minut resetu).
- GraphQL endpoint jest nieco bardziej tolerancyjny niż pełne renderowanie stron, bo generuje mniej ruchu.
Strategia:
- Rotacja IP per listing — każda strona hotelu z nowym IP. Użyj flagi
-session-z unikalnym ID dla każdego locationId, aby zachować spójność cookie/token w obrębie jednego obiektu. - Backoff wykładniczy — przy 429 lub 403 odczekaj 60s, potem 120s, potem 300s. Nie natychmiast retry.
- Limit współbieżności — maksymalnie 5–10 równoległych żądań z różnych IP. Większa współbieżność podnosi podejrzenie.
- Paginacja — offset 0, 10, 20... aż do pustej odpowiedzi lub błędu. Większość hoteli ma 50–500 opinii, więc 5–50 stron.
- Opóźnienie między żądaniami — 2–5 sekund losowo, aby symulować ludzkie zachowanie.
Sticky sessions
Flaga -session- utrzymuje to samo IP przez całą sesję. Jest kluczowa, bo token X-Requested-By i cookie są powiązane z IP. Jeśli IP zmieni się w trakcie pobierania opinii z jednego hotelu, sesja zostaje zerwana. Przykład:
# Sesja per hotel — IP się nie zmienia w obrębie jednego locationId
session_id = f"hotel-{location_id}"
proxy = f"http://user-country-GB-session-{session_id}:PASSWORD@gate.proxyhat.com:8080"
Najczęstsze błędy i pułapki
- Brak impersonifikacji TLS —
requestsihttpxmają fingerprint TLS różny od Chrome. Używajcurl_cffizimpersonate="chrome". - Brak cookie z początkowego GET — GraphQL endpoint wymaga cookie ustawionego przez stronę listing. Zawsze najpierw GET, potem POST.
- Zbyt wysoka współbieżność — 50 wątków z jednego IP to gwarantowany ban. Limituj do 5–10.
- Ignorowanie
robots.txt— sprawdź robots.txt TripAdvisor przed scrapowaniem. - Brak backoff> — retry natychmiast po 403 tylko pogarsza sytuację. Wdróż wykładniczy backoff.
- Zbyt agresywne paginowanie — niektóre listingi mają limit offset (np. max 1000). Poza tym endpoint zwraca pustą odpowiedź.
Etyczne scrapowanie i kiedy użyć oficjalnego API
Scrapowanie danych publicznych jest legalne w wielu jurysdykcjach, ale ma granice. Kilka zasad:
- Agreguj, nie identyfikuj — zbieraj statystyki (średnia ocena, rozkład, trendy), a nie profile użytkowników. Nazwy użytkowników TripAdvisor to pseudonimy, ale w połączeniu z treścią opinii mogą stanowić dane osobowe.
- RODO dla recenzentów z UE — jeśli recenzent jest z UE, jego opinia może zawierać dane osobowe. Zgodnie z RODO, przetwarzanie danych osobowych wymaga podstawy prawnej. Agregacja anonimowa jest bezpieczniejsza.
- CFAA w USA — Computer Fraud and Abuse Act karanie „nieautoryzowany dostęp”. Scrapowanie publicznych danych bez logowania jest ogólnie akceptowane, ale omijanie zabezpieczeń technicznych (CAPTCHA, anti-bot) może być traktowane jako naruszenie. Zobacz wytyczne FTC.
- Szukaj oficjalnego API — TripAdvisor oferuje Content API dla partnerów komercyjnych. Jeśli budujesz produkt komercyjny, oficjalne API jest bezpieczniejsze, legalne i stabilniejsze. Scrapowanie powinno być ostatecznością.
Jeśli Twoja aplikacja wymaga danych TripAdvisor na produkcji, zacznij od oficjalnego Content API. Scrapowanie ma sens tylko dla badań, analizy rynku lub gdy API nie obejmuje Twoich potrzeb.
Kluczowe wnioski
- TripAdvisor lazy-loaduje opinie przez GraphQL endpoint
/data/graphql/ids— nie ma ich w statycznym HTML. - Datacenter IP są blokowane przez DataDome niezależnie od nagłówków — używaj proxy rezydencjalnych.
curl_cffizimpersonate="chrome"jest wymagane do poprawnego fingerprintu TLS.- Realistyczny limit: 50–100 listingów/godzina per IP, z 5–10 min reset po soft-block.
- Sticky sessions (
-session-) zachowują spójność cookie/token/IP. - Geo-targetowanie (
-country-GB-city-london) daje spójne wyniki z lokalnymi użytkownikami. - Zbieraj dane zagregowane, nie osobiste — RODO i CFAA mają zastosowanie.
- Sprawdź oficjalne Content API TripAdvisor, zanim zdecydujesz się na scrapowanie.
ProxyHat dostarcza infrastrukturę proxy dla web scrapingu i SERP tracking. Zobacz ceny i dostępne lokalizacje, aby zacząć.






