Expedia Reviews Scraper
Pricing
from $3.00 / 1,000 result scrapeds
Expedia Reviews Scraper
Scrapes guest reviews from Expedia hotel/product pages. Extracts ratings, review text, stay info, management responses, photos, and hotel metadata (address, coordinates, star rating, rating distribution).
Pricing
from $3.00 / 1,000 result scrapeds
Rating
0.0
(0)
Developer
Reviewly
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
🏨 Expedia Reviews Scraper — Extract Hotel Reviews Without an API Key
Turn any Expedia hotel page into a clean dataset of guest reviews — scores, review text, stay details, traveller photos, and management responses — plus the hotel's full rating profile.
- ⭐ Scrape every guest review of a property, newest-first, with full text and stay info
- 🏨 Capture the hotel profile: address, coordinates, star rating, guest rating, rating distribution, category scores (cleanliness, location, staff…)
- 🛡️ Anti-bot protection handled for you — a fast HTTP client with a real browser TLS fingerprint, with an automatic hardened-browser fallback and IP rotation when blocked
- 📅 Incremental scraping with a date cutoff, perfect for daily or weekly review monitoring
- 📦 Export to JSON, CSV, or Excel, or pull results straight into your app via the Apify API
Paste an Expedia hotel URL, press Start, get data.
📌 What This Actor Does
Give it one or more Expedia hotel/product page URLs — any slug form works, on any Expedia country site:
| URL form | Example |
|---|---|
| Long slug | https://www.expedia.co.uk/Kastoria-Hotels-Hotel-Anastassiou.h6136437.Hotel-Information |
| Short path | https://www.expedia.com/h17369936.Hotel-Information |
| Minimal slug | https://www.expedia.com/Hotel.h600217.Hotel-Information |
The country site you use (expedia.com, expedia.co.uk, …) decides the language and currency of the responses. For every property the Actor returns one structured record combining the hotel profile and as many reviews as you ask for, pulled from Expedia's own internal GraphQL API — not from fragile HTML selectors.
⚙️ Input
| Field | Type | Default | Description |
|---|---|---|---|
startUrls | array | — | Expedia hotel page URLs (objects with url, or plain strings). |
maxReviews | integer | 1000 | Max reviews per property. 0 = no limit. |
reviewSort | select | newest | newest, relevant, highest, or lowest. |
targetDate | string | — | ISO date cutoff — stop at reviews older than this (forces newest-first). |
includeRatingsOnlyReviews | boolean | true | Include reviews that carry only a score, no text. |
proxy | object | — | Proxy configuration. Residential recommended. (proxyConfiguration is accepted as an alias.) |
{"startUrls": [{ "url": "https://www.expedia.co.uk/Kastoria-Hotels-Hotel-Anastassiou.h6136437.Hotel-Information" }],"maxReviews": 200,"reviewSort": "newest","targetDate": "2024-01-01","proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }}
📤 Output
One dataset record per property:
{"propertyId": "6136437","name": "Hotel Anastassiou","description": "Morning coffee by Kastoria Lake sets the tone…","starRating": 2,"rating": 8,"superlative": "Very good","reviewCount": 70,"ratingCounts": [{ "rating": 10, "count": 21, "percent": 30, "description": "10 - Excellent" }],"categoryRatings": [{ "label": "Cleanliness", "score": 8.4 },{ "label": "Location", "score": 8.2 }],"address": {"street": "1st km Highway Kastoria-Athens","city": "Kastoria","region": "Western Macedonia","postalCode": "52100","country": "GRC"},"coordinates": { "latitude": 40.498285, "longitude": 21.266815 },"image": "https://images.trvl-media.com/lodging/…","priceRange": "from £40 - per night (includes taxes and fees)","petsAllowed": "Pets not allowed…","url": "https://www.expedia.co.uk/Kastoria-Hotels-Hotel-Anastassiou.h6136437.Hotel-Information","reviews": [{"reviewId": "65f2cdfd6167c03fb85cefe7","rating": 10,"ratingOutOf": 10,"superlative": "Excellent","title": "Love this town!!","text": "Nice hotel. Nice room. Nice people!!…","locale": "en_US","date": "2024-03-14","dateText": "14 Mar 2024","verified": true,"stayInfo": "Stayed 1 night in Mar 2024","themes": ["Liked: Cleanliness, staff & service…"],"helpfulCount": 0,"reviewer": "Jaymi","travelers": [],"photos": ["https://a.travel-assets.com/ugc/hotel-reviews/…"],"managementResponses": [{ "header": "Response from Anastassiou hotel on 8 Apr 2025", "date": "2025-04-08", "text": "Thank you…" }]}]}
Reviews are null-dated (with dateText kept) only when the site locale renders dates in a non-English format.
🧠 How It Works
- Fast path (default): an HTTP client with a genuine Firefox TLS/HTTP2 fingerprint (impit) fetches the hotel page, earns Expedia's Akamai Bot Manager cookies, and parses the hotel profile from the page's schema.org microdata and server-rendered state.
- Reviews via GraphQL: the Actor then pages through Expedia's internal
PropertyReviewsQueryAPI (25 reviews per request) on the same session, absorbing rotated cookies on every response. - Fallback on hard blocks: if an IP is challenged, a fingerprint-hardened Firefox (Camoufox) solves the check (DataDome interstitial reload loop included), and impit replays the browser's own identity — same proxy session, same Firefox shape, no client hints.
- IP rotation: each start URL gets up to 8 fresh proxy sessions before giving up; a working session is reused across properties.
- When a fallback attempt fails to clear, a debug screenshot + challenge iframe details are stored in the run's key-value store so failures are self-diagnosing.
Maintenance notes
- The reviews API uses a persisted query hash (
REVIEWS_QUERY_HASHinsrc/scraper.js). If Expedia bumps its client, requests returnPersistedQueryNotFound— recapture the hash from the browser DevTools Network tab (filtergraphql, operationPropertyReviewsQuery, copyextensions.persistedQuery.sha256Hash). - The GraphQL gateway requires a
client-infoheader (CLIENT_INFOinsrc/scraper.js); any recent value captured the same way works.
🖥️ Running Locally
pnpm install# optional, only needed for the browser fallback:npx camoufox-js fetch# input lives in storage/key_value_stores/default/INPUT.jsonpnpm start
Set the Apify run timeout to ≥ 900 s — a run that needs several browser solves can take a while.