Expedia Hotel Search Scraper avatar

Expedia Hotel Search Scraper

Pricing

from $0.84 / 1,000 hotel-listeds

Go to Apify Store
Expedia Hotel Search Scraper

Expedia Hotel Search Scraper

Scrape every hotel Expedia and Hotels.com list for a destination and your dates. Just add place names and get hotel name, guest rating, nightly price, stay total with taxes, neighbourhood, photos and the booking link. $1.20 per 1,000 properties.

Pricing

from $0.84 / 1,000 hotel-listeds

Rating

0.0

(0)

Developer

BonCross API

BonCross API

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

7 days ago

Last modified

Categories

Share

What is Expedia Hotel Search Scraper?

Expedia Hotel Search Scraper returns up to 200 hotels for a destination and your dates, and each one has the nightly rate and the stay total as two separate numbers. Type a city, a neighbourhood, an airport or a landmark, pick the dates, and you get one row per hotel from Expedia or from Hotels.com.

Why people choose it over a general hotel scraper:

  • You get the price the Expedia website shows. Checked against a live expedia.com page in the same minute, the totals matched on 90 of 90 hotels and the nightly rates on 92 of 92. The app can show a lower price on some hotels, and that isn't what you get here.
  • Two prices per hotel, and a flag that tells you which one has tax in it. priceTotal is what a guest pays. pricePerNight is what the site displays, and pricesIncludeTax says whether tax is already inside it.
  • It's quick. Five cities at 200 hotels each came back as 959 rows in 8 seconds.
  • Expedia does the filtering. Property class, guest rating, nightly price, property type, meal plans, free cancellation, pay later and anything else on its filter panel are applied by the site, and a hotel it filters out is never charged.
  • $1.20 per 1,000 hotels on the Free plan, $0.84 on Business, with proxy usage and platform usage included.

BonCross Verified means we tested this actor against the live site before release and kept the record:

  • 47 of 47 live checks on its inputs and filters passed on 7 October 2026
  • 12 destinations run the same day across Expedia and Hotels.com, in two Expedia markets: 199 hotels, none empty
  • A guest-rating or distance sort Expedia does not apply gets an uncharged error row

What else it does:

  • Searches several destinations and several date ranges in one run
  • Reads Expedia in 40 country markets, each in its own currency, and Hotels.com in the United States
  • Returns the guest rating out of 10, the site's word for it and the review count
  • Gives you gallery photos and the booking link for each hotel, with your dates in it
  • Sorts the way the site does, with eight orders to choose from
  • Remembers which hotels earlier runs returned, and can hand you only the new ones
  • States the currency each price is really in, whatever you asked for
  • Tells you why in a row when a destination can't be resolved or a search isn't answered

People use it to build a priced hotel index for a city and refresh it on a schedule, to find the competitor set around a station or a landmark, and to watch how an area's prices move as a date approaches. It's also the usual first step before a rate-grid pull: pick the hotels worth it here, then pass their IDs to Expedia Room Rates Scraper.

What do you get for each hotel?

🏨 Hotel name and property IDSite (Expedia or Hotels.com)
📍 Neighbourhood or areaDistance from the landmark you searched
⭐ Guest rating out of 10Rating in words, and review count
💵 Price per night💰 Stay total with taxes and fees
Both prices as displayed💱 Currency the price is really in
Whether tax is in the nightly pricePre-tax nightly price, where it is one
📅 Check-in, check-out and nightsAdults, child ages and rooms priced
🖼 Gallery photos🔗 Link to the booking page
Destination and market searchedTimestamp of the run

How to search Expedia hotels with it

There's nothing to install. You fill in a form and download a spreadsheet.

  1. Create a free Apify account and open Expedia Hotel Search Scraper.
  2. Type place names into Destinations, for example "Chicago", "Santorini" or "Yellowstone National Park".
  3. Set the check-in and check-out dates. If you leave them empty, the stay starts 30 days from today for one night.
  4. Choose how many hotels you want per destination (50 unless you change it) and any filters.
  5. Click Start, then download the hotels as Excel, CSV, JSON, XML or HTML.

How much does it cost?

EventFree planStarterScaleBusiness
actor-start, once per run$0.002$0.002$0.002$0.002
destination-resolved, per destination and date range the site answered$0.0005$0.0005$0.0005$0.0005
hotel-listed, per property returned$0.0012$0.00108$0.00096$0.00084

Enterprise plans pay the Business price.

$1.20 per 1,000 properties on the Free plan, $0.84 on Business. That's the whole price: proxy usage and platform usage are included, and there's no proxy to set up.

  • 20 destinations × 50 properties = 1,000 rows: $0.002 + 20 × $0.0005 + 1,000 × $0.0012 = $1.212 ($0.852 on Business).
  • One destination, 200 properties: $0.002 + $0.0005 + 200 × $0.0012 = $0.2425 ($0.1705 on Business).

Apify's Free plan includes $5 of credits a month. That's about 80 searches of 50 hotels each, or roughly 4,000 hotels, before you pay anything.

You pay nothing for a destination the site never answered, or for one that couldn't be resolved to a place.

⬇️ Input

Give it place names. Each one is matched against the site's own place list: an exact name match wins, an airport name or code gives you the airport, and otherwise the most general place is used. "Kyoto" gives you the city, not Kyoto Station. If you want a station or a neighbourhood, name it.

You have two limits. "Maximum hotels per destination" (1 to 200, default 50) applies to each destination and date range separately. "Maximum rows for the whole run" stops the run once that many rows exist in total, and 0 means no limit.

A weekend in two cities

{
"destinations": ["Chicago", "Barcelona"],
"checkIn": "2026-11-13",
"checkOut": "2026-11-15",
"maxHotelsPerDestination": 20
}

Cheapest first, well rated, under a nightly price

{
"destinations": ["Savannah"],
"checkIn": "2026-11-13",
"checkOut": "2026-11-15",
"sortBy": "PRICE_LOW_TO_HIGH",
"minRating": 8,
"maxPricePerNight": 250,
"maxHotelsPerDestination": 50
}

One destination across three stays, refundable with breakfast

{
"destinations": ["Cape Town"],
"checkIn": "2026-11-13",
"checkOut": "2026-11-15",
"stays": ["2026-12-31_2027-01-02", "2027-02-10_2027-02-13"],
"freeCancellationOnly": true,
"mealPlans": ["breakfast"],
"adults": 2,
"rooms": 1
}

The same search on Hotels.com

{
"destinations": ["Chicago", "Lake Tahoe"],
"site": "hotels",
"checkIn": "2026-11-20",
"checkOut": "2026-11-22",
"maxHotelsPerDestination": 15
}

A scheduled run that returns only hotels you haven't seen

{
"destinations": ["Santorini"],
"checkInDaysAhead": 30,
"nights": 2,
"dedupStoreName": "santorini-hotels",
"onlyNew": true,
"maxItems": 500
}

Filters are Expedia's own. "Minimum property class" keeps that class and above. "Minimum guest rating" uses the site's 7+ / 8+ / 9+ filter and then checks each row. The two nightly price bounds use its budget filter, in the market's currency. "Property types" and "Meal plans" (breakfast, half_board, full_board, all_inclusive) work the same way, as do "Only fully refundable properties" and "Only reserve now, pay later". For anything else on the panel, put its label in "More Expedia filters": "Pool", a neighbourhood, a hotel brand.

Sorting. You get the six orders on Expedia's menu plus two it accepts without showing: guest rating only, and price blended with its picks. Price orders follow the price the market puts first, which is the nightly rate in Japan and the stay total in the US.

Guests and rooms. Your party is the number of adults (1 to 14, default 2) plus one age per child. "Rooms" prices a booking of several rooms, not one room several times: the nightly rate stays per room and the stay total covers them all, which is how the site quotes it. Asking for more rooms can return fewer hotels, because a room with one unit left can't be booked twice. That's a real answer about availability.

Market decides the money. Expedia runs a separate site per country, 40 of them, and each quotes its own currency. Choose Japan and you get JPY, choose the United States and you get USD, for the same hotel on the same dates. Nothing is converted afterwards. With Market on Auto, a search uses the US site in USD. Where a market offers USD, that's the default for "Currency". Eleven of the forty markets offer a choice (the US offers ten currencies). Elsewhere the market's own money is used and the run log says so. Clear the field to take the market's own.

Compare nightly prices inside one market only. 18 of the 40 markets quote a nightly rate with tax already in it, and there the stay total is exactly the nightly rate times the nights. The other 22 add tax on top. priceTotal is what you'd pay either way, and that's the number to compare on.

Hotels.com works on the United States market only. Each run reads one site. Run it twice if you want to compare the two.

Label language is English unless you pick the market's own language, which translates the site's wording (such as ratingText) and leaves prices unchanged. "Include photos" is on by default. Turn it off for a smaller row.

For developers

  • maxHotelsPerDestination is the per-search limit and maxItems the run-wide one. The price bounds are minPricePerNight and maxPricePerNight, the party is adults and childrenAges. stays takes CHECKIN_CHECKOUT lines, and every destination is searched for every stay.
  • With no checkIn, the window is checkInDaysAhead (default 30) and nights (default 1, up to 30), counted from the day the run starts. That keeps a scheduled run pointed at a moving window.
  • filters takes a label or field=value: hotelName=Hilton (a property-name search), bedroomFilter=2, availableFilter=SHOW_AVAILABLE_ONLY, amenities=POOL. A label matches whole words on that search's own panel, and the run log names the options it matched. The panel, with every option's code, is saved in the run's SEARCH_OPTIONS record. A label that matches nothing returns an error row for that search and no charge.
  • STATS records, per destination, the place chosen, the alternatives Expedia offered, and Expedia's own total for the filtered search.
  • sortBy values REVIEW_RELEVANT ("Guest rating + our picks") and DISTANCE are checked on every search against a recommended search asked at the same moment. If Expedia answers its default order, the search is asked again. One that stays unsorted returns an error row, uncharged, in place of the default order under the wrong name.
  • dedupStoreName names the store that remembers what you've had, and onlyNew returns only properties no earlier run returned.
  • maxConcurrency (default 4, up to 8) is how many searches are fetched at once. delayMs (default 0) pauses after each request, per parallel lane, and values above 2000 are treated as 2000. We'd leave both alone.
  • If the platform moves or restarts a run part-way, it carries on where it stopped. Searches already in the dataset aren't repeated, delivered or billed a second time. That was tested by restarting a 10-city run part-way, and no row appeared twice.

⬆️ Output

You get one row per hotel. This one is from a Chicago search run on 7 October 2026:

{
"id": "15849775-2026-11-13-2026-11-15",
"brand": "expedia",
"market": "us",
"hotelId": 15849775,
"name": "Hampton Inn Chicago West Loop Fulton Market Area",
"area": "Chicago",
"distanceText": null,
"rating": 9.2,
"ratingScale": 10,
"ratingText": "Wonderful",
"reviewCount": 1000,
"priceTotal": 593,
"pricePerNight": 249,
"pricesIncludeTax": false,
"pricePerNightExcludingTax": 249,
"priceText": "$249 nightly",
"priceTotalText": "$593 total",
"currency": "USD",
"checkIn": "2026-11-13",
"checkOut": "2026-11-15",
"nights": 2,
"photo": "https://images.trvl-media.com/lodging/16000000/15850000/15849800/15849775/12da6fa3.jpg?impolicy=fcrop&w=456&h=286",
"photos": ["https://images.trvl-media.com/lodging/16000000/15850000/15849800/15849775/12da6fa3.jpg?impolicy=fcrop&w=456&h=286"],
"url": "https://www.expedia.com/Chicago-Hotels-Hampton-Inn-Chicago-Downtown-West-Loop.h15849775.Hotel-Information?chkin=2026-11-13&chkout=2026-11-15",
"destination": "Chicago",
"regionId": "829",
"regionName": "Chicago, Illinois, United States of America",
"adults": 2,
"childrenAges": [],
"rooms": 1,
"scrapedAt": "2026-10-07T20:26:23.217Z"
}

Things worth knowing before you build on it:

  • pricePerNight and priceTotal aren't multiples of each other. Two nights at $249 comes to $593 here, not $498, because the US market adds taxes and fees on top. Use priceTotal to compare costs and pricePerNight for display.
  • priceTotal always includes taxes and fees. pricesIncludeTax tells you whether pricePerNight does too. It's true in markets such as the UK, Germany and France, and false in markets such as the US and Japan. Where it's false, the nightly price is also in pricePerNightExcludingTax. On 2 October 2026 it was filled on every priced row in the US, Japan, the UK, Germany and France, in English and in the site's own language. It's null on a hotel with no price.
  • hotelId joins these rows to the room rates, reviews and hotel details actors listed at the end.
  • id combines the property ID and the stay dates, and one hotel on two date ranges gives you two distinct rows. regionId is the resolved destination, which makes a run reproducible without resolving the name again.
  • distanceText is filled when your destination is a landmark or a station, where there's something to measure from ("2.2 km from Kyoto Station"). It's null for a whole-city search.
  • A destination that couldn't be resolved, or a search the site never answered, is written as a row with an error and is never charged.

How many hotels can you get, and how fast?

One request covers one destination and one date range and returns the whole list at once, up to 200 properties per request. Several destinations and date ranges are searched at the same time. Measured on Apify on 2 October 2026:

RunRowsRun time
Kyoto, one stay, 15 properties14 to 154 to 7 s
Tokyo, Osaka and Kyoto, two stays each, 50 properties per search291 to 2928 s
Tokyo, Osaka, Kyoto, Sapporo and Fukuoka, 200 properties each9598 s
10 Japanese cities, 100 properties eachabout 9658 to 10 s

A run over 20 destinations at 50 properties each returns roughly 1,000 rows, and thousands of destination-and-date searches fit in the default one-hour run limit.

Not every hotel has every field. On a 20-property Tokyo sample, name, price, stay total, photo and link were present on all 20, and the guest rating on 17. A hotel with too few reviews has no rating yet.

FAQ

Are these the prices the website shows?

For Expedia, they are: each price is the one the Expedia website shows a traveller in a browser for that market and those dates. The app can show a lower price on some properties, because it has app-only discounts, and those aren't returned. Member-only rates aren't included either. You get what an anonymous visitor sees.

How do I search a neighbourhood, a station or an airport?

Name it. A neighbourhood, a station such as "Kyoto Station", a landmark such as "Yellowstone National Park" or an airport code is resolved on its own. A bare city name gives you the whole city.

Why don't the nightly price and the stay total divide evenly?

The total includes taxes and fees, and in 22 of the 40 markets the nightly price doesn't. Both numbers come from the site, and neither is derived from the other.

Why did my sorted search return an error row?

Expedia at times answers its default order when asked for "Guest rating + our picks" or "Distance". The actor checks for that on each search and asks again. If the list still isn't sorted, you get an error row and no charge, which is better than the default order labelled as something else. Run it again later, or use one of the price orders, which aren't affected.

Where did the amenities go?

Expedia's result cards no longer list them: 0 of 220 cards measured on three markets had any. Expedia Hotel Details Scraper returns each property's amenities, along with the star class and the coordinates, which a search row doesn't have either.

Can I search Hotels.com instead?

On the United States market, set Site to Hotels.com. Hotels.com Japan isn't supported. Ask for it and the run returns one error row that says so, at no charge. Expedia Japan (expedia.co.jp) is fully supported.

How do I get more than 200 hotels for a city?

200 per destination and date is what the site's own list returns. Search the city's neighbourhoods one by one to go deeper. A hotel returned by two searches for the same dates has the same id, which makes the overlap easy to drop.

Do I need proxies or an Expedia account?

Neither. There's no login, no cookie of yours is used, and proxy usage is included in the price with nothing to set up.

Everything it reads is what Expedia and Hotels.com show a visitor who isn't signed in. There's no account access and no private data involved. Collecting public search results this way is generally lawful in the UK, EU and US. How you use what you collect is your responsibility, including under GDPR where data identifies a person, and under the site's own terms.

What are the limits?

  • A nightly price from one market can't be set against another's. Use the stay total.
  • Star ratings aren't returned. The site publishes no star class on a search result. "Minimum property class" is still applied by the site, and the guest rating out of 10 is returned.
  • Coordinates aren't on a search row.
  • A property with too few reviews has a null rating, not zero.
  • A Hotels.com search the site doesn't answer returns an error row and costs nothing. The row says Hotels.com didn't answer on this run. It's never an empty result.
  • Hotels.com US search prices can differ from hotels.com on some hotels. Measured side by side, 10 of 77 hotels were priced differently, by up to about 11%, most of them higher. Expedia prices aren't affected.
  • Most markets quote one currency only. Each row states the currency its price is actually in.

Run it on a schedule or from your own code

A daily price index needs no code. Create an Apify Schedule, leave the dates empty and set days ahead, and the window moves with the calendar. A webhook can fire when a run finishes, and the rows can go to Google Sheets, Slack, Make, Zapier or Airbyte.

From code, one call runs a search and returns the hotels:

curl -X POST "https://api.apify.com/v2/acts/boncross~expedia-hotel-search/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"destinations":["Chicago"],"checkIn":"2026-11-13","checkOut":"2026-11-15"}'

An AI agent can do the same through the Apify MCP server (mcp.apify.com), where the actor appears as boncross/expedia-hotel-search. Ask it for the cheapest well-rated hotels in a city for your dates and it has priced rows to answer from.

More from BonCross

Your feedback

Seen a price that doesn't match the Expedia page, or a destination that resolves to the wrong place? Open an issue on this actor's Issues tab with the destination, dates and market you ran. We read each report and answer there.