Which review sites can be scraped without a browser
Probed on 2026-08-29 through datacenter and residential pools, with plain HTTP/2 and with Chrome- and Firefox-impersonating TLS stacks, and with a real browser where nothing else passed. This is what each source actually returned, including the two that a headed Chrome could not read either.
The table
Every row was measured on 2026-08-29 through Apify's residential and datacenter pools, with three fresh sessions per pool, plus a no-proxy control wherever a block looked universal. "Plain client" means HTTP/2 with a Chrome user agent and no TLS impersonation; "impersonating client" means curl_cffi with a named browser profile.
| Source | What it takes | Reviews per request | The catch |
|---|---|---|---|
| Hostelworld | Plain client, datacenter | 10-50 per page; one property paged out 1,022 | Public JSON API, no key, no auth, no referer. per-page above 50 is a 400. There is no silent-empty case at all |
| Zoover | Impersonating client, datacenter | Up to 50 per call, cursor-paged | The page needs a TLS fingerprint (a plain client gets Cloudflare 403 from the same IP); the API is explicitly allowed in robots.txt. Omit size and it returns exactly one review with the true totalCount |
| Indeed | Chrome profile, datacenter | 20 per page | firefox147 is 403 on every attempt. start past the last page returns HTTP 200 with page one again |
| Kurzurlaub | Plain client, datacenter | 20 per page | An AJAX endpoint that needs no token and no header, returning an HTML fragment inside JSON. German-language, and the ratings are mostly title plus category scores |
| Booking.com | Plain client (review call only) | 25 per call | The property page is AWS-WAF-walled and took 54-77 s in a browser; the review endpoint is not walled |
| TripAdvisor | Firefox 147 profile, residential | 10 per page (15 on restaurants) | Datacenter is refused on every profile. Chrome profiles are refused even from a clean home IP |
| HRS | Plain client, residential | 4 per hotel page | Datacenter gets Akamai Access Denied 1 time in 3. The full review list is a separate API that returns CloudFront 400 without a header we could not resolve |
| Despegar | Chrome profile, residential | 4 per hotel, and that is the page's ceiling | Two headed-browser network captures recorded zero review-bearing XHRs. The analytics beacon says it: review_count: 4511, total_comments: 4 |
| Trustpilot | Browser for the token, then plain client | 200 per filtered view | AWS WAF in challenge mode on every path, including direct with no proxy. The token expires at about five minutes |
| Amazon | Plain client, datacenter escalating to residential | 8-13 per product | A ceiling, not a block. /product-reviews/ is login-walled and returns the sign-in page as HTTP 200 |
| AliExpress | Plain client, datacenter | 20 on page 1, up to 500 after | Page 1 ignores your page size; the backend shuffles, so a deep walk sees repeats |
| Yelp | Nothing on these pools | 0 | DataDome hard-block ('t':'bv') on both pools; the identical request from a home IP returns 200 and 1.7 MB. Pure IP reputation |
| Expedia / Hotels.com | Browser | 0 | Akamai sensor plus a captcha PWA. POST /graphql answers 429 "Provisioned request rate has been exceeded" on datacenter, residential and direct |
| Glassdoor | Nothing that was tried | 0 | Cloudflare interactive challenge: 23 of 23 requests 403 across 11 TLS profiles, both pools and direct; headed real Chrome never cleared it either. Page 2 is an explicit 401 login-required |
Four rules that came out of the evidence
1. The impersonation profile is per-site, not per-vendor. TripAdvisor and Despegar are both DataDome. TripAdvisor answers a Firefox 147 fingerprint and refuses Chrome. Despegar answers Chrome and refuses Firefox 147 on both pools, eight attempts out of eight. Indeed behaves like Despegar. Probe both profiles before you write a source off — one of them flipped a source from "browser-only" to "one HTTP request per page".
2. The library version is part of the fingerprint. curl_cffi 0.13.0 maps the firefox alias to Firefox 135, which TripAdvisor hard-blocks. Version 0.16.2 maps it to Firefox 147, which passes. Same code, same IP, same second — opposite verdicts. Pin the profile by name (impersonate="firefox147"), not by alias.
3. A browser is sometimes strictly worse. Headless Chromium through residential got Despegar's hard block while a plain impersonating client on the same pool got 200. The browser is a different fingerprint, not a better one.
4. The site usually tells you where its API is. Zoover's robots.txt has an Allow: line for the review endpoint it wants crawled. Hostelworld's server-rendered Nuxt config prints HOSTELWORLD_API_URL in the HTML. Two of three sources handed over the endpoint with no reverse-engineering.
The traps that produce wrong data rather than errors
These are worse than blocks, because they succeed:
- Zoover's missing
size.POST /api/getReviewswithout asizeparameter returns HTTP 200 with exactly one review — and the correcttotalCountnext to it. A scraper that trusts the payload reports one review for a property with eleven. - Indeed's page-one wrap-around.
?start=past the last page returns HTTP 200 with page one's twenty reviews andcurrentPage: 1. A "page until empty" loop never terminates and re-bills the same rows forever. Stop on the declared found-review count or on the disappearance of the next link. - Amazon's 200-status sign-in page. The login wall on
/product-reviews/is served as a 200 of about 325 KB. Check for the sign-in marker, not the status code. - eBay's decoy cards. A results page renders 62 cards: 60 real plus 2 in an
aria-hiddenclipped container titled "Shop on eBay". A zero-result search still renders around 21 related cards, so "we got rows" is not the same as "the search matched". - AliExpress's page-1 size. Page 1 returns 20 rows no matter what page size you ask for; later pages honour up to 500. A
pageSize=100walk loses reviews 21-100 of every product and never notices.
What this means when you are buying a scraper rather than building one
Ask what the ceiling is. A source with a hard public ceiling — Amazon at 8-13, Despegar at 4, Trustpilot at 200 per view — cannot be scraped past it by anyone, so a listing that does not name the number either has not measured it or is not telling you. And ask what an empty result means: on the sources above, a refusal, a genuinely empty property and an unknown id are three different outcomes, and only one of them is worth retrying.
The review scraper comparison carries the ceiling per source for everything in this suite. The per-source guides go deeper: TripAdvisor, Booking.com, Trustpilot, Amazon, Indeed, AliExpress and eBay.
FAQ
What is the difference between a block and a ceiling?
A block changes with your IP or your TLS fingerprint: the same URL that is 403 on datacenter is 200 on residential, or 403 for a Chrome profile and 200 for a Firefox one. A ceiling is what the page renders for anyone who is not signed in — Amazon's 8-13 reviews, Despegar's 4 comments, Trustpilot's 200 per view. Rotating proxies past a ceiling just costs more for the same rows.
Does a headless browser always beat a plain HTTP client?
No, and twice here it is worse. Headless Chromium through a residential proxy got Despegar's hard block, while a plain impersonating client on the same pool got 200. On Glassdoor, headed real Chrome — automation flag disabled, through residential and again from a clean home IP with no proxy — sat on "Just a moment..." for 45 seconds and never got in.
Which impersonation profile should I use?
Both, and test. TripAdvisor and Despegar are both DataDome, and the profile that passes one is the profile the other refuses: TripAdvisor needs Firefox 147 and refuses Chrome; Despegar needs Chrome and refuses Firefox 147 on every pool. Indeed matches Despegar. There is no vendor-level answer, only a per-site one.
How do you find a site's JSON API without a browser?
Two places paid off repeatedly. robots.txt Allow: lines — Zoover explicitly allows its own review API — and the server-side rendering config blob, where Hostelworld's Nuxt payload prints its API base URL in plain text. Both handed over the endpoint with no reverse-engineering at all.
Run TripAdvisor Reviews Scraper on Apify →
Other actors used on this page: apify.com/kestrel/booking-reviews-scraper, apify.com/kestrel/trustpilot-reviews-scraper, apify.com/kestrel/indeed-company-reviews, apify.com/kestrel/hostelworld-reviews-scraper, apify.com/kestrel/zoover-reviews-scraper, apify.com/kestrel/despegar-hotel-ratings, apify.com/kestrel/ebay-search-scraper.