Google Hotels Scraper — Prices by OTA, Calendar & Reviews
Pricing
from $2.00 / 1,000 hotels
Google Hotels Scraper — Prices by OTA, Calendar & Reviews
Scrape Google Hotels: hotels of any search with price, rating, sentiment by aspect, amenities and photos; the full price ladder across Booking, Expedia, Agoda and the official site with free-cancellation dates; nightly price calendars; review texts. No login. Empty or failed rows are never charged.
Pricing
from $2.00 / 1,000 hotels
Rating
0.0
(0)
Developer
Oswaldo Carabano
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
11 days ago
Last modified
Categories
Share
Google Hotels Scraper — prices by booking site, price calendar and reviews
Scrape Google Hotels for any city, any dates and any number of guests. Get every hotel of a search with its price, rating, review breakdown, sentiment by aspect, amenities, photos and nearby places — or go one level deeper and get the full price ladder across booking sites (Booking.com, Expedia, Hotels.com, Agoda, Trip.com, the hotel's official website and more), a nightly price calendar, or review texts.
No login. No cookies. No browser. From $2.00 per 1,000 hotels. Rows that fail, come back empty or repeat are never charged.
What you can use it for
| If you are… | Use | You get |
|---|---|---|
| A revenue manager or hotel owner tracking rate parity | hotel-prices | Your official-site price next to every OTA, the % gap to the cheapest offer, free-cancellation deadlines |
| A travel startup or metasearch building a hotel database | hotel | Up to ~160 unique hotels per city with coordinates, class, rating, amenities and photos |
| An analyst studying seasonality or event pricing | price-calendar-day | The cheapest, official and highest price for each check-in date of a range |
| A reputation or market-research team | review | Review texts from Google, Tripadvisor, Trip.com and more, with scores and hotel replies |
| Anyone comparing cities, dates or group sizes | any | Dates, currency, adults and children ages go into the Google request itself, so prices are real for that stay |
Four outputs, one per run
Pick outputType. Every run produces one kind of row, so your exports stay clean.
outputType | One row per | Price | What is inside |
|---|---|---|---|
hotel (default) | hotel of a search | $0.002 | name, ids, coordinates, address (when shown), class, rating, review histogram, sub-scores, sentiment by aspect, featured price with and without taxes, total for the stay, deal badge, check-in/out times, website, description, amenities, photos, nearby places with travel times |
hotel-prices | hotel | $0.0035 | everything above plus every booking-site offer (median 23 per hotel) with nightly and total prices, with and without taxes, free-cancellation date, member deals, official-site price and parity, address, hotel phone, AI review summary |
price-calendar-day | hotel × check-in date | $0.003 | lowest, official and highest price for that night, every offer, free-cancellation count |
review | review | $0.001 | full text, score and scale, source site, approximate date, hotel reply, per-aspect scores, highlight tags |
Actor start: $0.00001 (platform minimum). Error rows, duplicates, hotels without any priced offer, sold-out nights and reviews without text: $0.
Measured, not promised
Every number on this page comes from our own measurements against the live site in October 2026, with its sample size. Fields with a measured fill rate of 0% are not listed.
Hotel rows — n = 706 hotels, 20 cities, 14 countries (13 Oct 2026)
Populated fields per hotel: median 27 of 28 (minimum 17, 90th percentile 28).
| Field | Filled |
|---|---|
| name, ids, coordinates, rating, review count, rating histogram, photos, nearby places, sub-scores, country | 100% |
| price, price with taxes, total for the stay, currency | 99.7% |
| amenities | 96.7% |
| official website | 95.9% |
| sentiment by aspect (6–32 aspects per hotel) | 92.5% |
| hotel class (stars) | 86.5% (Germany 25%: Google only shows official classes there) |
| description | 82.2% |
| check-in / check-out time | 78.0% |
| deal badge ("23% less than usual") | 23.4% |
Price ladders — n = 36 hotel pages in 6 countries (13 Oct) + 60 in 3 countries (14 Oct 2026)
- Offers with a price per hotel: median 23, 90th percentile 30, maximum 42.
- Total price for the stay on 1,205 of 1,205 offers.
- At least one offer with free cancellation on 48 of 60 hotels, with the deadline date.
- Address on 100% of hotel pages, hotel phone on 29 of 30, AI review summary on 37 of 60.
- Official website among the offers on 46 of 60 hotels; member-only deals on 24 of 60.
- The headline search price was the cheapest offer only 20 times out of 36 — the ladder tells you more than the headline.
50 test runs on Apify — 14 Oct 2026
- 50 of 50 runs succeeded: 23 Google markets, 16 languages, all four outputs, filters, hotel links, sizes from 1 to 510 rows, and bad inputs (which end green with an explanatory error row that is not charged).
- Charged = delivered in 50 of 50 runs (3,608 rows); 0 duplicate rows.
- Default input
{}: 20 hotels in 7–11 seconds (6 runs, including 2 on the current build). Slowest run: a 31-night calendar for 10 hotels (310 hotel-nights, 285 with prices) in 5 min 12 s (5 min 48 s on the current build, which caps requests in flight atmaxConcurrency). - Non-empty fields per row (all fields, including the dates and guests you asked for): hotel median 46 (n = 1,857) · hotel-prices 61 (n = 120) · price-calendar-day 29 (n = 451) · review 19 (n = 1,180).
- The same hotel keeps the same
entityid between runs (58 of 58 hotels seen in two identical runs had the same name; coordinates within 10 m).
Reviews — n = 20 hotels × 3 pages = 600 reviews (13 Oct 2026)
- 100% with text. 10 per request, paginated until your limit.
- Sources seen: Google, Tripadvisor, Priceline, Trip.com, IHG, hotels' own sites.
- Reviewer names, profile links and avatars are never collected.
How it compares
Figures read from the public Apify Store API on 13–14 Oct 2026 (users and run outcomes over the last 30 days) and from each actor's published input and output schemas. We did not run anyone else's actor.
| This actor | Most-used alternative | Second most-used | Most complete alternative | |
|---|---|---|---|---|
| Users, last 30 days | new | 520 | 517 | 47 |
| Failed or timed-out runs, last 30 days | 0 of 50 varied test runs (14 Oct 2026, 23 markets, all four outputs) | 43.6% of 42,351 | 5.3% | 0.3% |
| Price per hotel row | $0.002 | $0.00499 | $0.001 + $0.005 per run start | $0.004 + $0.002 per offer |
| Hotels per run | many cities × up to 300 hotels | many | one | many |
| Price ladder by booking site | ✅ median 23 offers, one charge | — | — | ✅ charged per offer |
| Price calendar | ✅ up to 31 dates × many hotels | — | ✅ one hotel | ✅ |
| Review texts | ✅ | — | — | ✅ |
| Sentiment by aspect | ✅ 92.5% | — | — | declared |
| Free-cancellation deadline per offer | ✅ | — | — | declared |
| Hotel phone and address | ✅ (hotel-prices) | — | — | declared |
| Output fields declared in its schema | 98 | 20 | 0 | 70 |
| Non-empty fields per hotel row, measured | median 46 (n = 1,857 rows) | not published | not published | not published |
| Unknown city charged? | no: rows are charged only when the place Google searched matches what you typed; a guessed city is an error row, $0 (0 of 120 made-up names charged, 14 Oct 2026) | not stated | not stated | not stated |
| Duplicates across pages charged? | no (deduplicated by hotel id) | not stated | n/a | not stated |
Input
Everything has a default: an empty input returns 20 hotels in Lisbon for a 2-night stay two weeks from today, in under 10 seconds (7–11 s in 6 runs on 14 Oct 2026).
| Field | Default | Notes |
|---|---|---|
outputType | hotel | hotel, hotel-prices, price-calendar-day, review |
locations | ["Lisbon"] | as you would type them in Google Hotels; "Valencia, Spain" beats "Valencia". Type a city or neighbourhood, not a landmark (see Wrong-city protection) |
hotelUrls | [] | Google Hotels links with /travel/hotels/entity/<id>, or the id; only the id is read |
checkIn / checkOut / nights | today + 14 / — / 2 | prices are for exactly this stay |
adults / childrenAges | 2 / [] | going from 2 to 4 adults changed the price in 17 of 18 hotels we tested |
currency / language / country | USD / en / us | currency is set inside the request, never converted by us |
maxHotels | 20 | unique hotels per location (about 160 available for a big city) |
stars, minRating, maxPrice | any | applied by Google itself; in our test 100% of returned hotels matched |
amenities | [] | all must be present; "Pool", "Parking", "Wi-Fi", "Breakfast", "Kitchen" accept any variant |
sortBy | relevance | lowest/highest price, highest rating, most reviewed (sorted per location) |
includeVacationRentals | false | Google mixes them into ~10% of results |
calendarDays | 7 | check-in dates for price-calendar-day (1–31) |
maxReviewsPerHotel | 30 | for review |
maxConcurrency | 6 | requests in flight for the whole run (searches, hotel pages, calendar dates and reviews); 6 is the measured sweet spot at 512 MB |
Example: rate parity for 3 cities
{"outputType": "hotel-prices","locations": ["Madrid", "Barcelona", "Valencia, Spain"],"checkIn": "2026-12-15","nights": 3,"adults": 2,"currency": "EUR","language": "es","country": "es","maxHotels": 30,"stars": ["4", "5"]}
Output example (hotel-prices, shortened)
{"_type": "hotel-prices","name": "Embassy Suites by Hilton Miami International Airport","entity": "ChoI7J2s6622-ausARoNL2cvMTFiN2NzZnA2axAB","address": "3974 NW S River Dr, Miami, FL 33142","stars": 4, "rating": 3.6, "reviewCount": 6109,"currency": "USD","offerCount": 28,"lowestPrice": 106.7, "lowestPriceSource": "KAYAK.com","officialPrice": 153.16, "officialSource": "Embassy Suites by Hilton Miami International Airport","officialVsLowestPct": 43.5,"freeCancellationOfferCount": 0,"offers": [{"source": "Embassy Suites by Hilton Miami International Airport", "isOfficial": true,"price": "$153", "priceValue": 153.16, "priceWithTaxes": "$173", "priceWithTaxesValue": 173.08,"totalPrice": "$306", "totalPriceWithTaxes": "$346","freeCancellation": false, "freeCancellationUntil": null}],"checkIn": "2026-11-18", "checkOut": "2026-11-20", "nights": 2, "adults": 2}
Error rows look like this and are never charged:
{ "_type": "error", "error": "city-not-found", "message": "Google Hotels did not recognise \"zxqvwk\" as a place… This row is not charged.", "location": "zxqvwk", "cityResolved": null, "placeCheck": "no-place" }
Wrong-city protection
For text it does not recognise, Google Hotels sometimes guesses a real city and
returns its hotels anyway — "Qwzxkpqville Zzrt" came back as New York, "Blorptastic
Vrumm" as Vilnius, depending on the exit IP. Those rows would look perfect and be wrong.
So a search is delivered and charged only when the place Google searched
(cityResolved) is a name of what you typed:
- the same name, ignoring accents, case and "St."/"Saint" ("Medellin" → Medellín, "Shibuya, Tokyo" → Shibuya), or
- a known alternative name of the same city — other languages and scripts, and common abbreviations ("NYC" → New York, "Köln" → Cologne, "CDMX" → Ciudad de México, "Den Haag" → The Hague, "Bangkok" → กรุงเทพมหานคร), from GeoNames (CC BY 4.0), or from Wikidata for smaller places.
Otherwise you get one city-not-found row, not charged, with cityResolved (what
Google answered) and placeCheck (why it was refused: place-mismatch for a guessed
city, place-unconfirmed when the name check could not be completed). Never charged on
doubt. Measured on 14 Oct 2026 from three different exit routes: 0 of 120 searches for
24 made-up names charged, and 159 of 162 searches for 54 real cities in 20 languages
accepted. The 3 refused were "near Eiffel Tower", which Google maps to all of Paris: for
landmarks, type the city.
The run also writes ERRORS (every error, always present) and RUN_SUMMARY (delivered,
charged, duplicates, errors) to its key-value store.
Reliability
- Retries that change the exit IP, never hammer the same one: a throttled or refused request moves to a new session, then to another route, then waits (60 s and up, bounded by your run timeout), and only then writes an explanatory error row — not charged.
- The run finishes before its timeout and says what was left, instead of being cut.
- Resumable: if the platform migrates the run, nothing is delivered or charged twice.
- If Google changes its page format, the affected rows become
schema-changederror rows and the run stays green; it does not guess. - Stops cleanly at the maximum cost you set for the run.
FAQ
Is there a limit of hotels per city? Google returns about 18 hotels per page and
roughly 160 unique hotels in 10 pages for a large city. maxHotels goes up to 300; you
get what Google lists.
Why is the cheapest offer different from the featured price? Google's featured price
is not always the cheapest site. That is exactly what hotel-prices shows.
Do I need a proxy? No. The actor handles its own routes.
Are duplicates charged between runs? Deduplication is inside a run (by hotel id). Two separate runs over the same city deliver and charge each run's hotels.
Do you collect reviewer names? No: not the name, not the profile link, not the photo.
What is not included? Room-type names per offer and sponsored ads: they were empty in
our samples (0 of 1,205 offers), so we do not promise them. The hotel phone and address
come from the hotel page, so they are on hotel-prices rows, not on hotel rows. Rows from hotelUrls take their amenities from the hotel page, which names fewer of them (Wi-Fi and pools as generic "Wi-Fi" and "Pool"); the raw codes are always in amenityCodes.