Expedia Hotels Scraper - Prices, Ratings & Reviews avatar

Expedia Hotels Scraper - Prices, Ratings & Reviews

Pricing

from $1.00 / 1,000 results

Go to Apify Store
Expedia Hotels Scraper - Prices, Ratings & Reviews

Expedia Hotels Scraper - Prices, Ratings & Reviews

From $1/1K. Scrape Expedia.com hotel listings and reviews for any destination. Extract prices, ratings, review text, photos, location details, hotel information, and more in clean, structured data.

Pricing

from $1.00 / 1,000 results

Rating

5.0

(2)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

0

Bookmarked

68

Total users

17

Monthly active users

14 days ago

Last modified

Share

Expedia Hotel Scraper: Prices, Ratings & Reviews

Expedia Hotel Scraper turns Expedia hotel listings and guest reviews into structured data. Search any destination or paste property and search URLs, and get back hotel cards with prices, star ratings, guest ratings and photos for your chosen dates, or flip a toggle to pull individual review records instead. Filter by price, star rating and sort order, cap review depth per hotel, and export to JSON, CSV or Excel, or read the results straight through the API.

Why This Scraper?

  • Two ways in. Search by destination, or paste Expedia property and search URLs. Share links from the Expedia app (expe.onelink.me and similar) are resolved automatically to the canonical hotel page first.
  • Two outputs from the same input. Aggregate hotel cards by default, or turn on Scrape reviews only for individual review records, one row per review.
  • Every filter guests use. Check in and check out dates, adults, rooms, children with ages, minimum and maximum nightly price, star rating, and sort order.
  • Review depth on demand. Cap reviews per hotel, embed a sample of reviews inside each hotel card, or pull every review as its own record with sentiment, stay details and management replies.
  • 30 locales and 36 currencies. Cards and reviews come back in the guest's own language and currency.
  • Built for schedules. Incremental mode returns only new, updated and reappeared hotels on repeat runs against the same search or URLs, and a blocked run fails loudly instead of quietly returning an empty dataset.
  • Resume support. Continue an interrupted large destination pull without paying twice for hotels already collected in an earlier run.

Use Cases

  • Rate and price monitoring: track nightly prices, discounts and availability for a set of properties across a date range.
  • Reputation and sentiment analysis: pull every review for a property to find recurring compliments, complaints and how management responds.
  • Scheduled market watching: run the same destination or property list on a schedule with incremental mode and only pay for what changed.
  • Travel content and comparison sites: build destination guides with hotel photos, star ratings and pricing pulled straight from search results.
  • Competitive benchmarking: compare star rating, guest rating and price band for a shortlist of properties in one destination.

Data You Get

Sample shape: values are illustrative placeholders, not from a live record.

FieldExample
mode"search" (also "url", "reviews")
placeName"Hotel Example Paris"
hotelId"11111"
hotelUrlExpedia link to the property
hotelOverallRating9.2 (0 to 10 scale)
hotelRatingLabel"Wonderful"
hotelTotalReviews1843
hotelCategoryRatings{"Cleanliness": 9.4, "Staff": 9.3} (reviews mode)
provider"expedia"
locale"en_US" (reviews mode)
scrapedAt"2026-04-18T07:30:00.000Z"
extra.priceFrom / extra.priceFormatted420 / "$420 nightly"
extra.priceStrikeout"$600" (present when discounted)
extra.starRating5
extra.descriptionshort property description
extra.imagesgallery image URLs
extra.searchDestination / extra.checkIn / extra.checkOut / extra.adultsthe search and stay context used for this record
extra.reviewsup to Max Reviews per Hotel inline review objects, when Include reviews in hotel cards is on
reviewId / reviewTitle / reviewTextreview identity and body (reviews mode)
reviewRating / reviewRatingLabel10 / "Excellent"
authorName"Sarah"
reviewDate / stayDate"Oct 14, 2025" / "Stayed 3 nights in Oct 2025"
sentiment{"liked": ["location", "staff"], "disliked": []}
hotelResponse / hotelResponseAuthor / hotelResponseDatemanagement reply text, author and date
photosguest submitted photo URLs (reviews mode)

Scrape reviews only mode returns one record per review using the review fields above. Incremental mode adds changeType, changedFields, firstSeenAt and lastSeenAt to hotel card records so you can tell what changed since the previous run.

How to Use

  1. Pick a mode: search (by destination) or url (paste hotel or search URLs).
  2. Set Check in and Check out dates (required), plus adults, rooms, children, and any price, star rating or sort filters.
  3. Turn on Scrape reviews only for individual review records, or leave it off for hotel cards, and set Max items to control run size and cost.
  4. Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.

Search a destination:

{
"mode": "search",
"destination": "Paris",
"checkIn": "2026-11-10",
"checkOut": "2026-11-13",
"adults": 2,
"maxItems": 50
}

Filter by price and star rating:

{
"mode": "search",
"destination": "Tokyo",
"checkIn": "2026-11-10",
"checkOut": "2026-11-13",
"starRatings": ["4", "5"],
"minPrice": 150,
"maxPrice": 400,
"sortBy": "REVIEW"
}

Fetch specific hotels by URL:

{
"mode": "url",
"startUrls": [
{ "url": "https://www.expedia.com/Example-City-Hotels-Sample-Hotel.h11111.Hotel-Information" }
],
"checkIn": "2026-11-10",
"checkOut": "2026-11-13"
}

Reviews only for a destination:

{
"mode": "search",
"destination": "New York",
"checkIn": "2026-11-10",
"checkOut": "2026-11-13",
"reviewsOnly": true,
"maxItems": 500
}

Property URLs must be Expedia Hotel-Information pages, and search URLs must be Expedia Hotel-Search pages. Expedia app share links (expe.onelink.me, expe.app.link, trip.expedia.com) are followed automatically to the matching hotel; Hotels.com and Vrbo links are not supported by this actor.

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/expedia-universal-scraper").call(run_input={
"mode": "search",
"destination": "Paris",
"checkIn": "2026-11-10",
"checkOut": "2026-11-13",
})
for hotel in client.dataset(run["defaultDatasetId"]).iterate_items():
print(hotel["placeName"], hotel["extra"].get("priceFrom"))

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/expedia-universal-scraper').call({
mode: 'search',
destination: 'Paris',
checkIn: '2026-11-10',
checkOut: '2026-11-13',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

Resume and recurring updates

  • Resume (resumeFromRunId) continues one interrupted run: paste its run or dataset ID and the actor skips hotels already collected there, so you don't pay twice.
  • Incremental mode (incrementalMode) is for scheduled runs over the same destination search or URL list. Each hotel is classified NEW, UPDATED (with changedFields), UNCHANGED (suppressed and not billed unless emitUnchanged is on), REAPPEARED, or EXPIRED (only after a run that scanned the whole tracked scope, and only with emitExpired). stateKey names or shares the stored state. Scrape reviews only runs do not participate in incremental mode. With incremental mode off, output is exactly as before.

Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.

What gets written to the connector: a condensed, human-readable summary of each record, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.

  1. Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to the page where items should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

Input Parameters

ParameterTypeDefaultDescription
modestringsearchsearch (by destination) or url (paste hotel or search URLs).
destinationstring(none)City name for search mode, for example Paris, New York, Tokyo.
destinationIdstring(none)Optional numeric Expedia region ID, the number after .d in an Expedia URL. Skips destination resolution.
startUrlsarray(none)Expedia property or search URLs for url mode.
checkInstring1 dayCheck in date. Absolute (YYYY-MM-DD) or relative, e.g. 1 day. Required.
checkOutstring2 daysCheck out date. Absolute or relative, e.g. 2 days. Required.
adultsinteger2Adult guests, 1 to 14.
childrenarray[]Ages of children, 0 to 17, one entry per child.
roomsinteger1Rooms to book, 1 to 8.
minPriceinteger(none)Minimum nightly price filter.
maxPriceinteger(none)Maximum nightly price filter.
starRatingsarray[]One or more of 1 to 5. Empty means all star ratings.
sortBystringRECOMMENDEDRECOMMENDED, PRICE_LOW_TO_HIGH, PRICE_HIGH_TO_LOW, DISTANCE, PROPERTY_CLASS, or REVIEW.
reviewsOnlybooleanfalseOutput individual review records instead of hotel cards.
includeReviewsbooleanfalseEmbed up to Max Reviews per Hotel reviews inside each hotel card. Ignored when Scrape reviews only is on.
maxReviewsPerHotelinteger25Cap on reviews embedded per hotel card.
reviewsFromstring(none)YYYY-MM-DD. Only keep reviews on or after this date.
includeCategoryRatingsbooleantrueAttach aggregate category ratings (cleanliness, staff, and similar) to review records in Scrape reviews only mode.
currencystringUSD3 letter currency code for prices on hotel cards.
localestringen_USLanguage and region for card content and review language.
maxItemsinteger20Hard cap on total records saved to the dataset.
resumeFromRunIdstring(none)Continue one interrupted run; skips hotels already collected there.
incrementalModebooleanfalseReturn only new, updated and reappeared hotels on repeat runs against the same search or URLs.
stateKeystring(none)Name or share an incremental mode state. Left empty, the actor derives one from the search or URLs and filters.
emitUnchangedbooleanfalseAlso return (and bill) hotels unchanged since the last incremental run.
emitExpiredbooleanfalseAlso return (and bill) hotels no longer found, after a complete scan.
proxyobject(none)Proxy configuration. Prefilled to Apify's residential proxy group.
mcpConnectorsarray(none)Optional: send a summary of each record to apps you authorized under Integrations.
notionParentPageUrlstring(none)Notion connector only: page under which records are created.
maxNotifyListingsinteger50Cap on items written to each connector per run.

Output Example

Sample shape: values are illustrative placeholders, not from a live record.

{
"mode": "search",
"placeName": "Hotel Example Paris",
"hotelId": "11111",
"hotelUrl": "https://www.expedia.com/Example-City-Hotels-Sample-Hotel.h11111.Hotel-Information",
"hotelOverallRating": 9.2,
"hotelRatingLabel": "Wonderful",
"hotelTotalReviews": 1843,
"provider": "expedia",
"scrapedAt": "2026-04-18T07:30:00.000Z",
"extra": {
"searchDestination": "Paris",
"starRating": 5,
"description": "Recently renovated boutique hotel steps from the city center",
"priceFrom": 420,
"priceFormatted": "$420 nightly",
"priceStrikeout": "$600",
"currency": "USD",
"images": [
"https://images.example.com/lodging/sample-1.jpg",
"https://images.example.com/lodging/sample-2.jpg"
],
"checkIn": "2026-11-10",
"checkOut": "2026-11-13",
"adults": 2
}
}

Plan Requirement

This actor is prefilled to use a residential proxy connection, which Expedia access typically needs for a reliable run. Residential access comes from your Apify proxy settings; no separate third-party account is required. Adjust the proxy group under Connection if a run has trouble reaching results.

FAQ

How much does it cost?

You pay per record returned, plus a small surcharge for each hotel returned from a property URL in URL mode. Destination-search runs that only return hotel cards do not trigger that charge. The Pricing tab shows the current rates. Use Max items to cap the cost of any run.

This actor collects only publicly available listing and review data. You are responsible for how you use it: follow Expedia's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Prices and availability change constantly and are not guaranteed to still be bookable by the time you read them.

What is the difference between Resume and Incremental mode?

They solve different problems and are the actor's most common point of confusion. Resume (resumeFromRunId) continues one specific interrupted run so it doesn't restart from scratch. Incremental mode is for running the same destination search or hotel/search URLs again and again, for example daily, and getting back only the hotels that are new, changed, or gone since the last run.

Can I get only new or changed hotels on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Repeat runs then return only new, updated and reappeared hotels, and unchanged ones are not billed unless you turn on Emit unchanged.

Why did my run return fewer hotels than expected?

Price, star rating and destination filters narrow the result set, and Max items caps the total regardless of filters. A destination that doesn't resolve, or a search with no matching hotels for the chosen dates and filters, also returns fewer records without failing the run.

Why did my run fail instead of returning an empty dataset?

The run fails when Expedia blocks every single request in that run, even after retrying with a different session, or when Resume points at a run or dataset that can't be read (or clashes with existing incremental state for the same search). In the blocked case you get a clear failure message instead of a silent empty dataset. Retry in a few minutes, or switch the proxy to Residential with a different country. An unresolved destination or a search with genuinely zero matching hotels still succeeds, just with fewer or zero records.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

🔗 Want more travel data?

Pair this actor with these related scrapers from the same team:

🏨 Trip.com Hotels, Rooms & Reviews Scraper
Pull structured hotel listings from trip.com with prices, room types, amenities...
🏨 Traveloka Hotel Scraper
Scrape Traveloka hotels across Singapore, Malaysia, Indonesia, Thailand, Vietnam and the...
🏨 Booking.com Hotels, Prices and Reviews Scraper
Scrape booking.com hotels, apartments, villas and hostels. Search any destination with...
🏨 Vrbo Scraper
Extract vacation rental data from Vrbo.com by location, region, coordinates, property...
🏨 Yanolja Scraper
Scrape Yanolja (NOL), Korea's largest accommodations marketplace, by region or URL. Every...
🏨 Airbnb Scraper
Scrape Airbnb stays by destination or link: nightly and total price, rating breakdown...

👉 Browse all abotapi scrapers

💬 Support & custom scrapers

  • 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • 🛠️ Need another site, extra fields or a private build? Email abotapi@proton.me or message Telegram @abotapi.
  • ⭐ Enjoying it? A quick review on the actor page helps other users find it.