Google Hotels Scraper - Prices, Ratings, Review Topics
Pricing
Pay per event
Google Hotels Scraper - Prices, Ratings, Review Topics
Google Hotels scraper and hotels API: scrape hotel prices, ratings, OTA rates (Booking.com, Agoda, Expedia, Hotels.com), per-room pricing, amenities, hotel class, review topics and coordinates for any city, hotel URL or dates. Rate parity ready. Any currency, no API key, $2 per 1,000 hotels.
Pricing
Pay per event
Rating
0.0
(0)
Developer
An Tan Huynh
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
1
Monthly active users
15 days ago
Last modified
Categories
Share
Google Hotels Scraper: Hotel Prices by Date, Ratings & Review Topics
Get hotel prices from Google Hotels for any destination and any dates, in any currency. For every hotel you get the nightly price, the total stay price with taxes and fees, the star rating, the guest rating and review count, what guests praise or complain about (review topics), the amenities (Wi-Fi, breakfast, parking, pool, fitness, pets...), coordinates, nearby places, the hotel website and photos.
No API key, no browser, no login. Each search page loads in about 2 seconds, so 100 hotels take well under a minute.
🤖 One-click MCP for Claude Desktop, Cursor, ChatGPT
Install this scraper as an MCP tool for your AI agent in one click:
mcp.apify.com/?tools=actors,docs,zet46/google-hotels-scraper
Or paste this JSON into your MCP client config:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com/?tools=actors,docs,zet46/google-hotels-scraper"}}}
Then ask your agent, for example: "Find 4-star hotels in Lisbon under 150 EUR a night for 12-14 December with free cancellation."
What you can use it for
- Rate shopping and revenue management: check what competing hotels charge for the same nights.
- Price monitoring: schedule a run daily and track how prices change toward the stay date.
- Travel apps, AI agents and chatbots: real, current hotel prices and ratings for any city.
- Market research: hotel supply, price levels and guest sentiment per city or neighbourhood.
- Lead lists for the hospitality industry: hotel names, websites, class and location.
Input
| Field | Example | Notes |
|---|---|---|
queries | ["Paris", "resorts in Bali", "hotels near Times Square"] | A plain city name becomes "hotels in Paris" |
hotelNames | ["The Ritz-Carlton New York, Central Park", "Hotel Villa Igea Rome"] | Bulk mode: each name is resolved to its top Google Hotels match (1 row per name). Perfect for tracking a 50-100 hotel portfolio in a single run. |
hotelUrls | ["https://www.google.com/travel/hotels/entity/..."] | Track specific hotels by URL (see below). Use with or instead of queries. |
hotelIds | ["ChkIv7fPt_j0mNn6ARoMLWcvMTF2M3BiczA4EAE"] | Same as hotelUrls but with just the opaque Google Hotel ID (the token after /entity/ in a URL, or the googleHotelId field from a previous run). Faster and more deterministic for daily tracking from a saved ID list. |
checkIn | 2026-11-20, today, +30d, 6 weeks, today+14 | Absolute (YYYY-MM-DD) or relative. Default: 14 days from today. Use relative values with Apify Scheduler so each daily run always gets a fresh forward stay without hard-coding dates. |
checkOut | 2026-11-22, tomorrow, +37d, today+21 | Absolute or relative, same formats as checkIn. Default: one night after check-in. |
adults, children, rooms | 4, 2, 2 | Party size. Google only shows hotels that fit (6 adults won't see the 2-person rooms) |
childrenAges | [5, 10] | Optional ages for per-age pricing; its length overrides children |
currency | USD, EUR, GBP, JPY, VND | Any ISO code Google supports |
maxHotelsPerQuery | 40 | Up to 1000; about 18 new hotels per page |
onlyWithPrice | false | Skip, and don't pay for, hotels without a price for your dates |
maxPricePerNight, minPricePerNight | 150, 50 | Price band; hotels outside the band are skipped and not charged |
minHotelClass | 4 | Keep only hotels with at least this many stars (1-5) |
minRating | 4.0 | Keep only hotels whose Google guest rating is at least this high |
includeProviderPrices | true | Add the price from every booking site and the official website (see below) |
includeOtaReviews | true | Add per-site review aggregates (Tripadvisor, Trip.com) and Google's typical nightly price band (see below) |
sortBy | lowest_price | Post-fetch sort: lowest_price, highest_rating, most_reviewed. Leave empty to keep Google's organic order. |
propertyTypes | ["resort", "boutique"] | Keep only hotels whose property type, class or name contains any of these words. Empty = keep all. |
amenityCodes | ["pool", "wifi", "gym"] | Keep only hotels whose amenity list contains ALL of these keywords (case- and hyphen-insensitive — wifi matches Wi-Fi (free)). Forces the entity-page fetch (adds about 1 second and $0.002 per hotel). |
onlyFreeCancellation | true | Keep only hotels offering at least one rate with free cancellation on your dates. Same cost as includeProviderPrices. |
onlyEcoCertified | true | Keep only hotels Google flags as independently certified for sustainability (energy efficiency, water conservation, etc.). |
device | mobile | User-Agent for each hotel's entity page. mobile sometimes surfaces OTA app-only rates desktop hides. Listing search always uses desktop (parser requirement). |
useResidentialFallback | true | After two datacenter failures in a row, switch the rest of the run to Apify RESIDENTIAL proxies. The row gets proxyFallback: true. |
language, country | en, us | Google interface language and country |
{"queries": ["Paris", "Da Nang"],"checkIn": "2026-11-20","checkOut": "2026-11-22","adults": 2,"children": 1,"childrenAges": [8],"rooms": 1,"currency": "USD","minHotelClass": 4,"minRating": 4.2,"maxHotelsPerQuery": 40}
Provider prices: Booking.com, Agoda, Expedia, Trip.com, the official site...
Turn on includeProviderPrices to get, for every hotel, the full list of booking sites Google compares, cheapest first, with direct booking links:
"providers": [{"provider": "Generator Paris", "pricePerNight": 68.96, "pricePerNightText": "$69", "totalPrice": 137.92, "sponsored": false, "bookingUrl": "https://..."},{"provider": "Booking.com", "pricePerNight": 80.09, "pricePerNightText": "$80", "totalPrice": 160.18, "sponsored": false, "bookingUrl": "https://..."},{"provider": "Agoda", "pricePerNight": 159.3, "pricePerNightText": "$159", "totalPrice": 318.59, "sponsored": false, "bookingUrl": "https://..."},{"provider": "Trip.com", "pricePerNight": 218.5, "pricePerNightText": "$219", "totalPrice": 437.01, "sponsored": false, "bookingUrl": "https://..."}],"cheapestProvider": "Generator Paris"
This is what you need for rate parity checks: is the hotel cheaper on its own website or on an OTA?
OTA review aggregates and the typical price band
Turn on includeOtaReviews to pull extra signal from each hotel's Google page:
- Reviews from every travel site Google tracks — Tripadvisor, Trip.com and other OTAs — with the aggregate rating, total review count, a direct link to the full review page, and one recent sample review (author, time, stars, full text and a shorter snippet). Combine with the Google rating already in
rating/reviewsCountto see where guests land across platforms. - Google's typical nightly price for the dates and party you queried: a
priceRangewithminText,typicalTextandmaxText(strings with the currency symbol). This is the band Google shows under "this hotel typically costs between X–Y per night" and tells you where the current price sits — a bargain, typical, or expensive.
"otaReviews": [{"provider": "Tripadvisor", "rating": 4.5, "maxRating": 5, "reviewsCount": 1073,"hotelUrl": "https://www.tripadvisor.com/Hotel_Review-...","sampleReview": {"author": "Eliz-K_1988", "time": "3 weeks ago", "stars": 1, "maxStars": 5,"text": "As a loyal and regular guest of the hotel Ritz Paris, I am deeply shocked...","snippet": "As a loyal and regular guest of the hotel Ritz Paris, I am deeply...","link": "https://www.tripadvisor.com/ShowUserReviews-..."}},{"provider": "Trip.com", "rating": 4.3, "maxRating": 5, "reviewsCount": 45,"sampleReview": {"author": "Trip.com Member", "time": "10 months ago", "stars": 5, "maxStars": 5,"text": "Excellent service and good experience during the days that passed...","link": "https://www.trip.com/hotels/detail?hotelid=4968739..."}}],"priceRange": {"minText": "€1,776", "typicalText": "€2,000", "maxText": "€2,404"}
The entity page is already fetched when includeProviderPrices is on, so turning this on at the same time costs nothing extra. Standalone, it adds about one second per hotel for the extra fetch.
Track specific hotels every day
For daily price monitoring of a known set of hotels, use hotelUrls. Open the hotel on Google Travel, copy the URL (it looks like https://www.google.com/travel/hotels/entity/...) and paste it in. The actor fetches each hotel for your dates and returns the same row shape as a search, with providers when includeProviderPrices is on. Combine it with the Apify scheduler to build a price history for your competitors or your own hotels.
{"hotelUrls": ["https://www.google.com/travel/hotels/entity/ChkIjozRxbD1k88WGg0vZy8xMWY4czFyNnJiEAE","https://www.google.com/travel/hotels/entity/ChgIy_jSysWK04kvGgwvZy8xMWczNzJoMW0QAQ"],"checkIn": "2026-11-20","checkOut": "2026-11-22","currency": "EUR","includeProviderPrices": true}
If you've already stored the opaque Google Hotel IDs (output as googleHotelId on every row, same value as entityToken), feed them straight into hotelIds and skip the URL step:
{"hotelIds": ["ChkIjozRxbD1k88WGg0vZy8xMWY4czFyNnJiEAE","ChgIy_jSysWK04kvGgwvZy8xMWczNzJoMW0QAQ"],"checkIn": "2026-11-20","checkOut": "2026-11-22","currency": "EUR"}
Full entity URLs are accepted here too — the actor peels off the token automatically — so you can mix and match if your portfolio spreadsheet has both shapes.
Output
One row per hotel:
{"position": 3,"name": "Crowne Plaza Paris - Republique by IHG","hotelClass": 4,"rating": 4.1,"reviewsCount": 2995,"pricePerNight": 182,"pricePerNightText": "$182","totalPrice": 437.91,"totalBeforeTaxes": 364.98,"totalTaxesAndFees": 0,"currency": "USD","checkIn": "2026-11-20","checkOut": "2026-11-22","nights": 2,"latitude": 48.8674,"longitude": 2.3653,"checkInTime": "3:00 PM","checkOutTime": "12:00 PM","website": "https://www.ihg.com/crowneplaza/hotels/gb/en/paris/pardl/hoteldetail","description": "Bright rooms in a modern lodging with a stylish restaurant, a bar & a furnished terrace.","freeCancellation": true,"freeCancelUntilDate": "2026-11-19","freeCancelUntil": "Nov 19, 2026","freeCancelDeadlines": ["2026-11-19", "2026-11-20", "2026-11-22"],"ecoCertified": true,"sustainability": {"ecoCertified": true, "practices": ["Energy efficiency", "Water conservation"], "moreCount": 2},"nearbyPlaces": [{"name": "The Centre Pompidou", "category": "top_sights", "rating": 4.4, "reviewsCount": 57317,"description": "Avant-garde complex housing the National Museum of Modern Art.","travelTimes": [{"mode": "taxi", "duration": "7 min"}, {"mode": "walking", "duration": "25 min"}],"travelTime": "7 min taxi"}],"reviewTopics": [{"topic": "Location", "mentions": 342, "positive": 301, "negative": 16, "positiveShare": 0.95},{"topic": "Service", "mentions": 341, "positive": 266, "negative": 61, "positiveShare": 0.813}],"ratingDistribution": {"5": 1506, "4": 877, "3": 314, "2": 141, "1": 157},"ratingsBreakdown": {"cleanliness": {"positive": 134, "negative": 21, "mentions": 161, "positiveShare": 0.865},"location": {"positive": 301, "negative": 16, "mentions": 342, "positiveShare": 0.95},"service": {"positive": 266, "negative": 61, "mentions": 341, "positiveShare": 0.813}},"images": ["https://lh3.googleusercontent.com/..."],"amenities": ["Wi-Fi (free)", "Air conditioning", "Breakfast (extra charge)", "Parking (extra charge)", "Restaurant", "Bar", "Pet-friendly (extra charge)", "Business center"],"amenitiesUnavailable": ["Pools", "Hot tub", "Fitness center", "Spa"],"markdownContent": "# Crowne Plaza Paris - Republique by IHG\n4-star hotel · 4.1/5 (2995 reviews)\n**$182**/night · 437.91 USD total · 2026-11-20 → 2026-11-22\n\nBright rooms in a modern lodging with a stylish restaurant, a bar & a furnished terrace.\n\n**Amenities:** Wi-Fi (free), Air conditioning, Breakfast (extra charge), Parking (extra charge), Restaurant, Bar, Pet-friendly (extra charge), Business center\n\n[Open on Google Hotels](https://www.google.com/travel/hotels/entity/...)","searchQuery": "Paris","googleHotelsUrl": "https://www.google.com/travel/hotels/entity/...","mapsUrl": "https://www.google.com/maps?cid=...","cid": "...","scrapedAt": "2026-10-15T09:04:17+00:00"}
Two fields are built from the row and are LLM/UI friendly:
ratingsBreakdown— sentiment per standard category (cleanliness,location,service,value,rooms,sleep,food). Each value haspositive,negative,mentionsandpositiveShare(0–1). Only categories Google has data for are included;nullwhen the page carries no review topics.markdownContent— a short, LLM-ready markdown summary of the row (name, class, rating, prices, description, top amenities, cheapest offers, link). Drop it into a RAG pipeline or an agent context window without reformatting.freeCancellation—truewhen at least one price/offer on the hotel's Google page carries a free-cancellation badge. Populated after the entity-page fetch.freeCancelUntilDate/freeCancelUntil/freeCancelDeadlines— multi-language deadline parser (EN/DE/FR/ES/IT/PT/NL/ZH/JA).freeCancelUntilDateis the earliest cancellable date as ISO (YYYY-MM-DD),freeCancelUntilis the human-readable form (Nov 19, 2026), andfreeCancelDeadlinesis the sorted list of all unique deadlines when more than one is present (useful to pick the latest cancellable rate instead of the earliest). Set once the entity-page fetch runs.ecoCertified+sustainability— set when Google shows the independent sustainability panel.sustainability.practiceslists the top named practices (e.g.Energy efficiency,Water conservation) andmoreCountis how many extra practices sit under "View details".nearbyPlaces— top sights, airports and transit stops Google shows next to the hotel, withcategory, optionalrating+reviewsCount+description, and atravelTimeslist of{mode, duration}entries (walking, taxi, bus, transit...). The old shorthandtravelTimeis kept for backward compatibility.proxyFallback—truewhen the row was fetched after the run escalated to Apify RESIDENTIAL proxies. Useful to audit proxy health or spot rate-limiting.
The run also writes a RUN_INFO record to the default key-value store with the finished timestamp, item count, dates, currency, proxy groups + country, device, whether residential fallback activated, pax and the sort/filter you used — handy for audit logs or diffing two runs.
Proxies and country routing. Apify datacenter proxies do not support apifyProxyCountry (requests return 407 silently). The actor detects this and auto-promotes the proxy group to RESIDENTIAL so the country routing works. If you prefer to stay on datacenter, leave apifyProxyCountry unset (gl / country already localise Google itself).
Export as JSON, CSV, Excel or HTML, or read it through the Apify API and integrations (Make, Zapier, n8n, Google Sheets, webhooks).
Pricing
$2.00 per 1,000 hotels ($0.002 per hotel), with no monthly fee. Provider prices add $2.00 per 1,000 hotels, charged only when you turn them on and a price list is found. You pay only for hotels that end up in your dataset. With onlyWithPrice turned on, hotels without a price are skipped and not charged. On the Apify free plan you can scrape about 2,500 hotels a month at no cost.
Need one hotel's price for every date (cheapest dates, price calendar, rate parity over time)? Use Google Hotels Price Calendar.
Looking for apartments, villas and houses instead of hotels? Use Google Vacation Rentals Scraper.
Room rates: for booking sites that list them (usually the hotel's own website and Booking.com), each provider also has a rooms list: room name, price per night and total. Use it to compare the same room type across sites.
Use it from Python, JavaScript or any HTTP client
from apify_client import ApifyClient # pip install "apify-client>=3"client = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("zet46/google-hotels-scraper").call(run_input={"queries": ["Paris"], "checkIn": "2026-12-10", "checkOut": "2026-12-12", "currency": "EUR", "maxHotelsPerQuery": 50})for item in client.dataset(run.default_dataset_id).iterate_items():print(item["name"], item["pricePerNight"], item["currency"], item["rating"])
The same works with the JavaScript client (apify-client on npm) or a single HTTP call to https://api.apify.com/v2/acts/zet46~google-hotels-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN> with the input as the JSON body. You can also schedule runs and send results to Google Sheets, Slack, Zapier, Make or n8n.
More ready-to-run examples (Python and Node.js): github.com/huynhtanan/google-hotels-api. Step-by-step tutorial: Google Hotels prices with Python on dev.to.
Daily price tracking (competitor monitoring)
Track your competitors' prices over time: run the actor on a daily schedule, store each snapshot, and alert when a price drops.
- In Apify Console open the actor, click Schedule actor, pick a cron (e.g. daily at 09:00) and lock in the input (your competitor list in
hotelUrlsorqueries,checkIn,checkOut,currency). - Pull the dataset into your own database with a few lines of Python:
import os, sqlite3from apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])# Get the dataset from the latest finished run and append it to SQLiterun = client.actor("zet46/google-hotels-scraper").last_run().get()with sqlite3.connect("prices.sqlite3") as con:con.execute("CREATE TABLE IF NOT EXISTS prices (run_at TEXT, hotel TEXT, check_in TEXT, nightly REAL, PRIMARY KEY (run_at, hotel, check_in))")for h in client.dataset(run["defaultDatasetId"]).iterate_items():con.execute("INSERT OR REPLACE INTO prices VALUES (?,?,?,?)",(run["startedAt"], h["name"], h["checkIn"], h.get("pricePerNight")))
A complete, ready-to-run version (prints how each hotel moved vs the previous observation) is here: github.com/huynhtanan/google-hotels-api/blob/main/python/track_prices.py. Full walkthrough with the SQL for drop alerts: Daily price tracking for competitor hotels on dev.to.
You can also skip code and let Apify push each result to Google Sheets, Slack, Make, Zapier or n8n directly, via Integrations on the actor page.
Use it from AI agents (MCP)
See the one-click install block at the top of this README. Full MCP Apify docs: docs.apify.com/platform/integrations/mcp.
FAQ
Are the prices for my dates? Yes. Prices come from Google Hotels for the exact check-in and check-out dates you set. pricePerNight is the nightly price Google shows. totalPrice is the whole stay including taxes and fees.
Which currency? Any currency Google supports. Set currency to EUR, GBP, JPY and so on.
How many hotels can I get? Large cities return hundreds of hotels per search. To cover a city more completely, add searches by area, for example hotels in Le Marais, Paris.
Do I need proxies? No setup needed. The actor uses Apify Proxy (datacenter) by default, which gives more complete results than direct requests, and the cost is included in the price.
Is scraping Google Hotels legal? The actor collects only publicly visible hotel listings and prices, with no personal data. You are responsible for how you use the data and for complying with the laws and terms that apply to you.
Something missing or broken? Open an issue on the Issues tab. Fixes usually ship within a day.