Expedia Hotels Scraper — Prices, Ratings & Reviews
Pricing
from $2.50 / 1,000 results
Expedia Hotels Scraper — Prices, Ratings & Reviews
Scrape hotels from Expedia by destination and dates: name, nightly price, guest rating, reviews count, location, deals and link. Optionally attach real guest reviews per hotel (text, score, date, reviewer, manager replies). Export JSON/CSV for rate shopping, price intelligence and review analysis.
Expedia Hotels Scraper — Nightly Prices, Ratings, Deals & Guest Reviews
Scrape hotel listings, live nightly prices, guest ratings, review counts, promotional deal badges, and verified guest reviews from Expedia across any destination and travel date window. Built for hotel revenue management, OTA rate shopping, competitive benchmarking, and travel market intelligence.
⚡ At a glance
| Feature | Details |
|---|---|
| 🏨 Primary Target | Expedia (expedia.com) Hotel Search & Property Guest Reviews |
| 💰 Core Pricing & Rank Data | Lead nightly price (priceNightly), currency, all card price figures (allPrices), deal badges, organic/sponsored rank |
| ⭐ Ratings & Reviews | Overall guest score out of 10 (rating), ratingLabel (Exceptional, Wonderful, etc.), reviewCount, plus optional full review text |
| 🌍 Search Modes | 25 built-in global destinations, custom city/region names (customDestinations), or custom filtered startUrls |
| 📈 Pagination & 1,000+ Scale | Automated infinite-scroll + "Show more" expansion, multi-sort deep inventory discovery, and 25-city scaling for 1,000+ hotels |
| ⚡ Speed & Reliability | Fast prefill (30 hotels in ~35–60 seconds); automatic session rotation and past-date auto-adjustment |
| 📦 Bulk Export Formats | JSON, CSV, Excel (XLSX), HTML, XML, RSS, and direct Apify REST API / Webhooks |
🔎 Why scrape Expedia hotels & prices?
Expedia is one of the world's largest online travel agencies (OTAs), setting the benchmark for real-time hotel pricing, room availability, promotional discounting, and guest sentiment across thousands of global destinations. For revenue managers, hospitality groups, metasearch analysts, and travel tech teams, Expedia's search results represent a live pulse of hospitality supply and demand.
However, Expedia does not offer a public API for competitive rate shopping. Its search interface is a complex single-page application (SPA) that lazy-loads properties via infinite scroll, mixes sponsored ads with organic rankings, and enforces strict anti-bot rate limits. Manually tracking nightly rates across multiple check-in dates, party sizes, and competitor sets is impossible at scale.
This Expedia scraper automates the entire extraction process: it renders the live Hotel-Search results over residential proxies, scrolls through the full property list, extracts structured pricing and rating metrics, optionally attaches verified guest reviews, and deduplicates every property by hotelId.
Key reasons teams use this Expedia data extractor:
- 💷 Automated OTA rate shopping: Track your property's and competitors' exact nightly rates (
priceNightly) and total stay prices (allPrices) across future check-in/check-out windows. - 📊 Competitive set (CompSet) benchmarking: Compare guest ratings (
rating), review volumes (reviewCount), and promotional badges (dealBadge) across neighborhoods and markets. - 🏷️ Visibility & sponsored-placement auditing: Monitor organic search rank (
rank) versus paid sponsored placements (isSponsored) for target destination queries. - 💬 Guest sentiment & reputation intelligence: Enable
scrapeReviewsto extract verified guest review text, scores, sentiment themes (Liked: Cleanliness, staff & service), and hotel management responses. - 🌐 Multi-city hospitality market research: Aggregate 1,000+ hotel listings across dozens of cities to model seasonal ADR (Average Daily Rate) trends and supply distribution.
✨ What this Expedia scraper does
- ✅ Search by destination, dates & occupancy: Choose from 25 built-in top destinations, enter any city or landmark in
customDestinations(e.g.,"Reykjavik","Scottsdale","Santorini"), and configurecheckIn,checkOut,adults,rooms, andsortBy. - ✅ Custom
startUrlssupport: Paste any pre-filtered Expedia Hotel-Search URL (with star ratings, neighborhood filters, amenities, or price bounds applied in your browser). - ✅ Deep infinite-scroll & multi-sort pagination for 1,000+ hotels: Automatically scrolls and clicks Show more up to 120 iterations per page, and automatically expands across sort orders and 25 global cities when
maxItems/maxItemsPerSearchtargets 1,000+ properties. - ✅ Automatic past-date protection: If a saved task or input passes a
checkIndate in the past, the actor automatically shifts the stay window 30 days into the future so scheduled runs never fail with empty results. - ✅ Complete hotel card metrics: Extracts
hotelId,name,url,priceNightly,priceCurrency,allPrices,rating,ratingLabel,reviewCount,location,dealBadge,isSponsored,image,searchDestination,checkIn,checkOut,rank, andscrapedAt. - ✅ Optional verified guest reviews (
scrapeReviews): Extracts up tomaxReviewsPerHotelrecent reviews per property, includingreviewId, numericscore,scoreText,superlative,title,text,date,verifiedstatus,author,themes, andmanagerResponse. - ✅ Global deduplication: Deduplicates hotels by
hotelIdacross all pages, sort modes, and destinations within a run.
🎯 Use cases
| Role / Team | How they use this Expedia scraper |
|---|---|
| Hotel Revenue Managers | Schedule daily rate-shopping runs across 7-, 30-, and 60-day advance booking windows to optimize RevPAR and ADR. |
| OTA & Metasearch Analysts | Audit rate parity, promotional discounting (Member Price, Save 20%), and sponsored ad share (isSponsored). |
| Hospitality Investors & Consultants | Map hotel supply, price tiers, and guest rating distributions across target acquisition markets. |
| Vacation Rental & Short-Term Managers | Benchmark Airbnb/Vrbo nightly rates against comparable local hotel inventory on Expedia during peak events. |
| Guest Experience & Brand Teams | Extract recent guest reviews (scrapeReviews: true) to analyze competitor weaknesses and manager response rates. |
| Travel Data & BI Engineers | Feed structured JSON/CSV hotel pricing feeds into Snowflake, BigQuery, PowerBI, Tableau, or Google Sheets. |
📥 Input configuration
All parameters are optional. Leaving the input empty runs a multi-city sample across top global destinations.
| Parameter | Type | Default / Prefill | Description |
|---|---|---|---|
destinations | array<string> | Prefill: ["New York"] | Select one or more popular cities from the built-in 25-city dropdown (New York, Las Vegas, Orlando, Miami, London, Paris, Tokyo, Dubai, etc.). |
customDestinations | array<string> | [] | Enter any city, island, region, or landmark not in the dropdown (e.g., ["Bali", "Aspen", "Lisbon"]). |
checkIn | string | Prefill: "2027-03-15" | Check-in date in YYYY-MM-DD format. Past dates are automatically advanced to upcoming dates. |
checkOut | string | Prefill: "2027-03-17" | Check-out date in YYYY-MM-DD format. |
adults | integer | 2 | Number of adults per room (1–14). |
rooms | integer | 1 | Number of rooms (1–8). |
sortBy | string | "RECOMMENDED" | Sort order: RECOMMENDED, PRICE_LOW_TO_HIGH, PRICE_HIGH_TO_LOW, REVIEW, or DISTANCE. |
maxItemsPerSearch | integer | 0 (Prefill: 30) | Maximum hotels to collect per destination. Set 0 for all loaded hotels on the page, or 30 for a fast preview. |
scrapeReviews | boolean | false | When true, fetches recent guest reviews for each extracted hotel. |
maxReviewsPerHotel | integer | 10 | Maximum guest reviews to fetch per hotel when scrapeReviews: true. |
startUrls | array<object> | [] | Optional custom Expedia Hotel-Search URLs with advanced browser filters applied. |
proxyConfiguration | object | US RESIDENTIAL | Apify Proxy configuration. US Residential proxies are pre-configured and required for reliable access. |
maxConcurrency | integer | 1 | Parallel browser sessions (1–10). Keep at 1–2 for highest reliability and lowest proxy usage. |
Example 1: Fast prefill run (30 New York hotels)
{"destinations": ["New York"],"checkIn": "2027-03-15","checkOut": "2027-03-17","adults": 2,"rooms": 1,"sortBy": "RECOMMENDED","maxItemsPerSearch": 30,"scrapeReviews": false,"proxyConfiguration": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"],"apifyProxyCountry": "US"},"maxConcurrency": 1}
Example 2: Multi-city rate shopping for 1,000+ hotels
{"destinations": ["New York", "Las Vegas", "Orlando", "Los Angeles", "Miami","Chicago", "San Francisco", "London", "Paris", "Rome"],"customDestinations": ["Nashville", "Austin"],"checkIn": "2027-05-10","checkOut": "2027-05-14","adults": 2,"rooms": 1,"sortBy": "PRICE_LOW_TO_HIGH","maxItemsPerSearch": 120,"scrapeReviews": false}
Example 3: Deep hotel competitor analysis with guest reviews
{"destinations": ["Miami"],"checkIn": "2027-04-01","checkOut": "2027-04-04","maxItemsPerSearch": 25,"scrapeReviews": true,"maxReviewsPerHotel": 15}
📤 Output schema & field reference
Each hotel is saved as a structured JSON record. Below is a verified output item from a live run:
{"hotelId": "h40797","name": "Palace Station Hotel and Casino","url": "https://www.expedia.com/Las-Vegas-Hotels-Palace-Station-Hotel-And-Casino.h40797.Hotel-Information","priceNightly": 82,"priceCurrency": "USD","allPrices": [82, 82, 369, 369, 287, 287],"rating": 8.8,"ratingLabel": "Excellent","reviewCount": 4453,"location": "Las Vegas","dealBadge": "Member Price","isSponsored": true,"image": "https://a.travel-assets.com/media/meso_cm/PAPI/Images/lodging/1000000/50000/40800/40797/7c123e6b_b.jpg","searchDestination": "Las Vegas","checkIn": "2027-03-15","checkOut": "2027-03-17","scrapedAt": "2026-11-10T02:30:00.000Z","rank": 1}
🏨 Hotel Identity, Pricing & Ranking Fields
| Field | Type | Coverage | Description |
|---|---|---|---|
hotelId | string | 🟢 High (100%) | Unique Expedia property ID (e.g., "h40797", used for deduplication) |
name | string | 🟢 High (100%) | Official property name on Expedia |
url | string | 🟢 High (100%) | Direct canonical URL to the hotel's Expedia detail page |
priceNightly | integer | 🟢 High (~99%) | Lead nightly rate for the selected dates and occupancy |
priceCurrency | string | 🟢 High (~99%) | Currency code (e.g., "USD") |
allPrices | array<integer> | 🟢 High (~99%) | All numeric price points displayed on the card (nightly, total with taxes, strikethrough rate) |
dealBadge | string | 🟡 Conditional (~35%) | Promotional badge when active ("Member Price", "Save 20%", "Book now, pay later") |
isSponsored | boolean | 🟢 High (100%) | true if the card is a paid sponsored placement (Ad), false if organic |
rank | integer | 🟢 High (100%) | 1-based position of the hotel within the destination search results |
⭐ Guest Rating, Location & Context Fields
| Field | Type | Coverage | Description |
|---|---|---|---|
rating | number | 🟢 High (~99%) | Guest review score out of 10 (e.g., 8.8, 9.4) |
ratingLabel | string | 🟢 High (~97%) | Qualitative rating tier ("Exceptional", "Wonderful", "Excellent", "Very good", "Good") |
reviewCount | integer | 🟢 High (~98%) | Total number of verified guest reviews |
location | string | 🟢 High (~99%) | Neighborhood or city area displayed on the property card |
image | string | 🟡 Conditional (~25%) | Thumbnail image URL when present in initial DOM attributes |
searchDestination | string | 🟢 High (100%) | Destination query that produced the listing |
checkIn / checkOut | string | 🟢 High (100%) | Check-in and check-out dates (YYYY-MM-DD) used for pricing |
scrapedAt | string | 🟢 High (100%) | ISO 8601 timestamp when the property was extracted |
💬 Optional Guest Review Fields (when scrapeReviews: true)
| Field | Type | Coverage | Description |
|---|---|---|---|
reviewsScraped | integer | 🟡 Opt-in (100%) | Count of guest reviews attached to the hotel object |
reviews[].reviewId | string | 🟡 Opt-in (100%) | Unique review identifier |
reviews[].score | number | 🟡 Opt-in (100%) | Numeric review score out of 10 |
reviews[].scoreText | string | 🟡 Opt-in (100%) | Formatted score label (e.g., "9/10 Wonderful") |
reviews[].title / text | string | 🟡 Opt-in (~97%) | Guest review headline and full body text |
reviews[].date | string | 🟡 Opt-in (100%) | Localized submission date (e.g., "Jun 14, 2026") |
reviews[].verified | boolean | 🟡 Opt-in (100%) | true when flagged as a verified stay |
reviews[].author | string | 🟡 Opt-in (~98%) | Reviewer display name |
reviews[].themes | array<string> | 🟡 Opt-in (~65%) | Highlighted sentiment tags (e.g., ["Liked: Cleanliness, staff & service"]) |
reviews[].managerResponse | string | 🟡 Opt-in (~30%) | Official reply from the hotel's management team, when present |
🔁 Pagination & 1,000+ scale architecture
Expedia does not use numbered URL pages (?page=2); instead, it uses a virtualized infinite scroll feed with a "Show more" trigger. This scraper handles scale at three levels:
- Deep single-search scrolling: Within each destination, the browser scrolls and clicks
"Show more"up to 120 times untilmaxItemsPerSearchis reached or the city's inventory is exhausted. - Multi-sort inventory expansion: When you request
maxItemsPerSearch >= 300(ormaxItems >= 500) across 1–3 cities, the scraper automatically queues alternate sort orders (PRICE_LOW_TO_HIGH,PRICE_HIGH_TO_LOW,REVIEW,DISTANCE) to surface properties beyond a single feed's scroll depth. - 25-city global expansion: For large multi-market runs (
maxItems: 1000+), pass multipledestinations/customDestinations(or let the 25-city expanded default list run) with globalhotelIddeduplication.
⚙️ How to use
- Open the Actor in the Apify Console.
- Pick your
destinations(or addcustomDestinations/startUrls) and set yourcheckInandcheckOutdates. - Set
maxItemsPerSearch: use30for a fast preview,100–300for a deep city sweep, or0for all available listings. - Keep US Residential Proxy enabled (pre-filled by default).
- Click Start and export your hotel dataset to JSON, CSV, Excel, or API.
Calling via Node.js (apify-client)
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });const run = await client.actor('haketa/expedia-scraper').call({destinations: ['New York', 'Miami', 'Las Vegas'],checkIn: '2027-04-15',checkOut: '2027-04-18',adults: 2,maxItemsPerSearch: 50,scrapeReviews: false,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(`Extracted ${items.length} Expedia hotels`);
Calling via Python (apify-client)
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("haketa/expedia-scraper").call(run_input={"destinations": ["New York", "Orlando", "Las Vegas"],"checkIn": "2027-04-15","checkOut": "2027-04-18","adults": 2,"rooms": 1,"sortBy": "PRICE_LOW_TO_HIGH","maxItemsPerSearch": 60,"scrapeReviews": False,})for hotel in client.dataset(run["defaultDatasetId"]).iterate_items():print(f"{hotel['rank']}. {hotel['name']} ({hotel['searchDestination']}) — ${hotel['priceNightly']}/night | Rating: {hotel['rating']}/10 ({hotel['reviewCount']} reviews)")
Calling via cURL (REST API)
curl -X POST "https://api.apify.com/v2/acts/haketa~expedia-scraper/runs?token=YOUR_APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"destinations": ["Miami", "Chicago"],"checkIn": "2027-05-01","checkOut": "2027-05-03","adults": 2,"maxItemsPerSearch": 50,"scrapeReviews": false}'
📚 Built-In Destinations & Sort Order Reference
Supported sortBy Modes
sortBy Value | Expedia Ordering | Best Use Case |
|---|---|---|
"RECOMMENDED" | Expedia default relevance & commercial rank | Auditing organic vs. sponsored (isSponsored) visibility and market share |
"PRICE_LOW_TO_HIGH" | Lowest nightly price first | Discovering budget inventory and rate floors across a destination |
"PRICE_HIGH_TO_LOW" | Highest nightly price first | Benchmarking luxury 5-star resorts and penthouse/suite pricing |
"REVIEW" | Highest guest review score first | Identifying top-rated boutique and flagship competitors (rating >= 9.0) |
"DISTANCE" | Closest to city center / landmark | Mapping downtown core hotel supply and pricing density |
Built-In Global Destinations (destinations dropdown)
| Region | Included Cities |
|---|---|
| U.S. East & South | New York, Miami, Orlando, Washington, D.C., Boston, Nashville, New Orleans, Austin |
| U.S. West & Midwest | Las Vegas, Los Angeles, Chicago, San Francisco, San Diego, Seattle, Honolulu |
| Europe | London, Paris, Rome, Barcelona, Amsterdam |
| Middle East, Asia & Americas | Dubai, Tokyo, Bangkok, Cancun, Toronto |
| Any Other City Worldwide | Add any city, island, neighborhood, or airport code in customDestinations (e.g., ["Zurich", "Kyoto", "Tulum", "Sydney"]) |
🔄 Automated Hospitality & Rate-Shopping Workflows
- Daily CompSet Rate Matrix: Schedule the scraper to run every morning at 6:00 AM across your target cities and future check-in horizons (+7 days, +30 days, +60 days), piping
hotelId,name,priceNightly,dealBadge, andrankinto BigQuery, Snowflake, or Google Sheets. - OTA Promotional & Sponsored Ad Monitoring: Track which competitors are running
"Member Price","Save 20%", or paid sponsored placements (isSponsored: true) during high-demand conference or holiday dates. - Guest Review Sentiment Pipeline: Run weekly with
scrapeReviews: trueandmaxReviewsPerHotel: 20on your target destination to feed recent guest complaints,themes, andmanagerResponsedata into an LLM or BI dashboard.
💡 Pro tips for best results
- Keep
scrapeReviews: falsefor fast rate-shopping: Price and rating summary metrics (priceNightly,rating,reviewCount,dealBadge) are already extracted from the search cards. EnablescrapeReviews: trueonly when you need full review text. - Minimize proxy transfer cost: Non-essential images, fonts, media, and third-party ad trackers are automatically blocked during browser rendering so residential proxy bandwidth stays low and pages load faster.
- Rate-shop multiple stay lengths: Schedule separate tasks for 1-night weekday stays vs. 3-night weekend stays to capture length-of-stay (LOS) discount tiers.
⚠️ Honest limitations
- Requires US Residential Proxy: Expedia blocks standard datacenter IP addresses. The input pre-fills Apify's US Residential proxy group, and the crawler automatically rotates sessions if a residential IP hits a temporary rate limit.
- Thumbnail
imagecoverage: Because image assets are blocked during rendering to reduce residential proxy cost and speed up page loads,imageis populated only when the URL is already present in initial DOM attributes (~25%). All pricing, rating, location, and URL fields populate at ~98–100%.
❓ Frequently Asked Questions (FAQ)
Do I get exact prices for my check-in and check-out dates?
Yes. Both priceNightly and allPrices reflect the exact checkIn, checkOut, adults, and rooms parameters you specify.
What happens if I leave checkIn / checkOut in the past on a scheduled run?
The scraper automatically detects past dates and shifts them 30 days into the future (2-night stay) so recurring scheduled tasks never fail.
How many hotels can I extract per run? A single city search typically yields 30 to 250+ hotels, and multi-city or multi-sort runs scale cleanly to 1,000+ unique hotels.
Can I use custom Expedia search filters like 4-star+ or free breakfast?
Yes. Apply any filters on expedia.com in your browser, copy the resulting Hotel-Search?... URL, and paste it into startUrls.
How fast is the prefill run?
With the default prefill (destinations: ["New York"], maxItemsPerSearch: 30), the run typically completes in 35 to 60 seconds.
🔗 Related Travel & Hospitality Scrapers
- HRS Hotel & Reviews Scraper — Extract European & global hotel prices, ratings, and guest reviews from HRS.
- Furnished Finder Scraper — Extract mid-term furnished rentals and landlord leads.
- Eventbrite Scraper — Track major conferences and local events driving hotel demand surges.
- Meetup Scraper — Extract destination events and group activity.
📋 Changelog
- v1.2 (2026-11): Unlocked 1,000+ hotel scaling & fast prefill — added deep 120-step scroll pagination, automatic multi-sort expansion for high-volume single-city pulls, 25-city expanded default scaling, global
hotelIddeduplication, automatic past-date advancement, and a fast30-hotel prefill (< 60s). - v1.1 (2026-10): Added optional verified guest reviews enrichment (
scrapeReviews&maxReviewsPerHotel) with manager responses and sentiment themes. - v1.0 (2026-07): Initial release of the Expedia Hotels Scraper.