Google Hotels Scraper: Prices, Deals & Booking Sites
Pricing
from $2.00 / 1,000 hotels
Google Hotels Scraper: Prices, Deals & Booking Sites
Hotel prices from Google Hotels for any city, dates, guests and currency: price per night and for the stay with and without taxes, rating, stars, deal badges, amenities, location. Optional prices from every booking site Google lists. $2 per 1,000 hotels.
Pricing
from $2.00 / 1,000 hotels
Rating
0.0
(0)
Developer
Naveen Raja
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
17 hours ago
Last modified
Categories
Share
Get hotel prices from Google Hotels for any city, area, landmark or hotel, for your dates, guests and currency: price per night and for the whole stay (with and without taxes), guest rating, reviews, star class, Google's deal badges ("35% less than usual"), amenities, location and a link to the hotel on Google Hotels. Optionally add every booking site Google lists for each hotel (online travel agencies and the hotel's own site) with its price and free-cancellation flag.
Price: $2 per 1,000 hotels ($0.002 per hotel), or $4 per 1,000 hotels with booking sites ($0.004 per hotel), plus $0.0005 per run. No subscription and no extra usage fees: platform and proxy costs are included. Error rows and the run summary are free.
| You want | Rows | You pay |
|---|---|---|
| 20 hotels in one city (the default) | 20 | $0.04 + $0.0005 |
| 100 hotels in each of 10 cities | 1,000 | $2.00 + $0.0005 |
| 50 hotels in 5 cities with every booking site | 250 | $1.00 + $0.0005 |
| Daily price check of 30 hotels for a month | 900 | $1.80 + $0.015 |
Unofficial. This Actor is not affiliated with, endorsed by or sponsored by Google. Google Hotels is a trademark of Google LLC. See Legal before you use the data.
What you get
- One row per hotel with the same fields every time:
name,pricePerNight,totalPrice,pricePerNightBeforeTaxes,totalBeforeTaxesAndFees,taxes,fees,displayedPrice,currency,rating,reviewCount,hotelClass,dealBadge,amenities,latitude,longitude,googleHotelsUrl,propertyTokenand more (all fields). - Your currency, whatever the server's country: 72 currencies. Google's own web page ignores
curr=and uses the visitor's IP currency; this Actor asks Google's data endpoint for your currency directly (checked from Apify's US data centers and from an Indian IP). - Any stay: check-in date (a date, or relative like "30 days" for scheduled runs), check-out or number of nights (up to 30), adults and children's ages.
- Google's filters: sort by price, rating or reviews, minimum guest rating, hotel class, price range, free cancellation; plus hotels-only or vacation-rentals-only.
- Deep, clean result lists: up to 1,000 hotels per place (as far as Google's list goes), page by page, duplicates removed. Plain place searches keep later pages on the place Google matched on the first page, and any page that strays to another place or drops part of your query (a brand, "5 star", "cheap") stops the search before anything from it is returned or charged. For long lists, search a plain place and use the filters (see Performance and limits).
- Single hotels: a hotel name ("Ritz Paris"), a Google Hotels hotel link or a property token returns that one hotel, ideal for watching a list of hotels every day.
- Booking sites (optional): every site Google lists for the hotel with its nightly and total price, whether it is the hotel's official site, free cancellation and its deadline, plus the hotel's street address.
- Honest prices: Google shows some prices before taxes and others with taxes, depending on the visitor's country and local rules. Every row has the price with taxes and fees, the price before taxes, the taxes and the fees, and Google's displayed price with its basis.
- Clear errors: a place Google can't match, a search without results, a wrong date or link gets a free error row with the reason; the other searches still run.
Use cases
- Hotel price monitoring: schedule a daily run for your city or your competitors' hotels and chart how prices move for the same dates.
- Revenue management and rate shopping: compare a hotel's price across the booking sites and its own website (rate parity).
- Travel apps and deal alerts: find hotels flagged "less than usual" or "great price" for given dates.
- Market research: average nightly prices by city, star class or date; supply of hotels vs. vacation rentals.
- Event and seasonal pricing: compare the same city across many check-in dates in one run (see searches).
- Data for automations: a predictable JSON schema, one row per hotel, callable from the API, Make, Zapier or n8n.
How to use
- Add one or more places, hotel names or Google Hotels links (one per line), e.g.
hotels in Lisbon,Shinjuku Tokyo,Hilton London,Ritz Paris. - Pick the check-in date (empty = tomorrow) and the check-out date or nights, the adults and any children's ages.
- Pick the currency (default USD) and max hotels per place (default 20).
- Optional: turn on Add booking sites and their prices, and set filters (sort, rating, class, price range, free cancellation, property type).
- Run, then download the results as JSON, CSV or Excel, or use the API. A run summary is saved as the
SUMMARYrecord.
Input example
{"queries": ["hotels in Lisbon", "Shinjuku Tokyo", "Ritz Paris"],"checkInDate": "30 days","nights": 2,"adults": 2,"currency": "EUR","maxHotelsPerQuery": 50,"sortBy": "lowest_price","minRating": "4.0","includeOffers": false}
Searches with their own dates, currency or price range
searches runs several searches with different settings in one run; each entry overrides the main settings:
{"searches": [{"query": "hotels in Rome", "checkInDate": "2026-12-04", "nights": 3, "currency": "EUR"},{"query": "hotels in Rome", "checkInDate": "2026-12-11", "nights": 3, "currency": "EUR"},{"query": "hotels in Tokyo", "currency": "JPY", "maxPrice": 20000},{"query": "Ritz Paris", "adults": 1, "childrenAges": [8], "currency": "GBP"}],"maxHotelsPerQuery": 30}
Keys: query, checkInDate, checkOutDate, nights, adults, childrenAges, currency, minPrice, maxPrice. The main minimum / maximum price apply in each search's own currency, so set minPrice / maxPrice per entry when entries use different currencies (otherwise "150" means ¥150 for a JPY entry).
Output example
A real row from a cloud run on 22 Oct 2026 (a hotel token, 2 nights, EUR, with booking sites; booking sites shortened to 2 of 29):
{"status": "ok","query": "ChYI1YD9vLqNr5__ARoJL20vMGNrcnhxEAE","resolvedLocation": "Hotel Arts Barcelona","position": 1,"name": "Hotel Arts Barcelona","type": "hotel","category": "hotel","hotelClass": 5,"hotelClassText": "5-star hotel","rating": 4.5,"reviewCount": 4793,"pricePerNight": 480.55,"totalPrice": 961.09,"pricePerNightBeforeTaxes": 411.98,"totalBeforeTaxesAndFees": 823.97,"taxes": 82.38,"fees": 54.75,"displayedPrice": "€439","displayedPriceBasis": "before_taxes_with_fees","currency": "EUR","dealBadge": null,"dealPercentLessThanUsual": null,"dealType": null,"checkInDate": "2026-11-05","checkOutDate": "2026-11-07","nights": 2,"adults": 2,"childrenAges": [],"amenities": ["Wi-Fi", "Restaurant", "Bar", "Room service", "Breakfast", "Smoke-free property", "Beach access","Full-service laundry", "Kid-friendly", "Parking", "Pool", "Outdoor pool", "Accessible", "Fitness center","Spa", "Business center", "Kitchen in some rooms"],"unavailableAmenities": ["Hot tub", "Pet-friendly"],"propertyDetails": [],"latitude": 41.3870567,"longitude": 2.1964207,"address": "Carrer de la Marina, 19-21, Ciutat Vella, 08005 Barcelona, Spain","checkInTime": "3:00 PM","checkOutTime": "12:00 PM","website": "https://www.ritzcarlton.com/en/hotels/bcnrz-hotel-arts-barcelona/overview/?scid=f2ae0541-1279-4f24-b197-a979c79310b0","thumbnail": "https://lh3.googleusercontent.com/grass-cs/AABkmLftac4x...=s150-w92-h150-n-k-no","offers": [{"site": "Super.com", "pricePerNight": 439.36, "pricePerNightText": "€439", "totalPrice": 878.72, "totalPriceText": "€879","priceBasis": "before_taxes_with_fees", "isOfficialSite": false, "freeCancellation": false, "freeCancellationUntil": null, "isAd": false},{"site": "Hotel Arts Barcelona", "pricePerNight": 457.59, "pricePerNightText": "€458", "totalPrice": 915.19, "totalPriceText": "€915","priceBasis": "before_taxes_with_fees", "isOfficialSite": true, "freeCancellation": false, "freeCancellationUntil": null, "isAd": false}],"offersCount": 29,"cheapestOfferSite": "Super.com","propertyToken": "ChYI1YD9vLqNr5__ARoJL20vMGNrcnhxEAE","googleHotelsUrl": "https://www.google.com/travel/hotels/entity/ChYI1YD9vLqNr5__ARoJL20vMGNrcnhxEAE/prices?hl=en&gl=us&ts=CAESCgoCCAMKAggDEAAaHBIaEhQKBwjqDxALGAUSBwjqDxALGAcYAjICEAAqCwoJOgNFVVJiAggB","googleFeatureId": "0x12a4a30f13665d1b:0xff3ebc6ba79f4055","googleHotelId": "14542216924105561703","language": "en","country": "us","scrapedAt": "2026-10-22T12:16:42Z","error": null,"errorKind": null}
Output fields
| Field | Meaning |
|---|---|
status | ok for a hotel row (charged), error for a free error row |
query, resolvedLocation | Your entry, and the place (or hotel) Google matched it to |
position | Position in Google's list for this search (1 = first) |
name, type, category | Name; hotel or vacation_rental; Google's category (hotel, hostel, resort_hotel, ...) |
hotelClass, hotelClassText | Official stars (1-5) where Google shows them |
rating, reviewCount | Google guest rating (1-5) and number of reviews |
pricePerNight, totalPrice | Google's headline price for your dates (the rate on the hotel's card) including taxes and fees, per night and for the stay. A listed booking site can be cheaper. With booking sites on, all price fields come from the hotel's own answer, the same one as the sites. Null in the rare case Google gives no price breakdown (displayedPrice is then still set) |
pricePerNightBeforeTaxes, totalBeforeTaxesAndFees | The same rate before taxes and fees |
taxes, fees | Taxes and fees for the stay, as Google splits them (a city tax may be in either) |
displayedPrice, displayedPriceBasis | The nightly price exactly as Google shows it, and what it includes: before_taxes, before_taxes_with_fees (only when there are fees: the US "all-in except tax" display), with_taxes (taxes, not fees) or with_taxes_and_fees; null when it matches none of them |
currency | ISO 4217 code of every price in the row |
dealBadge, dealPercentLessThanUsual, dealType | Google's deal label, e.g. "35% less than usual" (deal / great_deal) or "GREAT PRICE for a 4-star hotel" (great_price) |
checkInDate, checkOutDate, nights, adults, childrenAges | The stay the prices are for |
amenities, unavailableAmenities | Amenity labels Google shows (e.g. "Free Wi-Fi", "Parking ($)", "Outdoor pool"), and those it marks as missing |
propertyDetails | Vacation rentals: "Entire apartment", "Sleeps 4", "2 bedrooms", ... |
latitude, longitude | Position (vacation rentals: rounded to 2 decimals, about 1 km) |
address | Street address of a hotel, with booking sites or for a hotel name / link (never for vacation rentals) |
checkInTime, checkOutTime, website, thumbnail | Check-in / check-out times, the hotel's own website (hotels only), one small photo URL |
offers, offersCount, cheapestOfferSite | With booking sites: each site's pricePerNight and totalPrice (and texts) as Google lists them, priceBasis (same values as displayedPriceBasis), isOfficialSite, freeCancellation, freeCancellationUntil, isAd (shown only as an ad); cheapest first |
propertyToken, googleHotelsUrl, googleFeatureId, googleHotelId | IDs and a Google Hotels link with the same dates, guests and currency |
language, country, scrapedAt | Settings used and run start time |
error, errorKind | Error rows only: the reason, and invalid_input, not_found, no_results, list_drifted, proxy_error, blocked, network, source_error or internal_error |
Dataset views: Hotels (photo, name, prices, rating, stars, deal, link), Booking sites, Details and Errors.
About prices and taxes
Google Hotels shows different visitors different things. Measured on 22 Oct 2026:
- The tax basis of the shown price varies: before taxes, before taxes but with fees (common for US visitors), with taxes but without fees, or everything, depending on the visitor's country and local rules. That's why every row has
pricePerNight/totalPricealways with taxes and fees (from Google's own price breakdown), the pre-tax amounts, the taxes and fees, and the shown price with its basis. - The headline price is not always the cheapest site.
pricePerNightis the rate Google puts on the hotel's card; with booking sites on,offers(cheapest first) may list a lower price, often on a different tax basis (priceBasis).priceBasisis null when the sites' prices don't line up with the headline rate (for example a different room). - Google's "lowest price" sort follows the displayed price (often before taxes), so rows are not always in
pricePerNightorder. - Hostels: some dormitory listings mix per-bed and per-room amounts in Google's breakdown (e.g. taxes as large as the base price). Treat
taxes/feesfor dorm beds with care. - Prices can depend on the visitor's country (booking sites price by market). With the default Apify Proxy the requests come from Apify's data centers, mostly in the US. The Country setting changes Google's local settings, not the visitor's country.
Pricing
Pay per event: you pay only for hotels in your dataset.
| Event | Price | When |
|---|---|---|
| Hotel | $0.002 | One hotel row without booking sites |
| Hotel with booking sites | $0.004 | One hotel row with at least one booking site ("Add booking sites" on). Rows where Google lists no booking site, or where the sites could not be read, cost $0.002 |
| Actor start | $0.0005 | Once per run |
Error rows, hotels skipped by your filters or without a price, duplicates, hotels from a result page that strayed to another region, and the SUMMARY record are free. Set a maximum cost per run in Apify Console: the Actor stops cleanly at that limit and never fetches what it can't charge for.
Use it from the API
curl -X POST "https://api.apify.com/v2/acts/fairfetch~google-hotels-scraper/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \-H "Content-Type: application/json" \-d '{"queries": ["hotels in Lisbon"], "checkInDate": "30 days", "nights": 2, "currency": "EUR", "maxHotelsPerQuery": 20}'
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_API_TOKEN>")run = client.actor("fairfetch~google-hotels-scraper").call(run_input={"queries": ["Ritz Paris", "hotels in Rome"], "checkInDate": "2026-12-04", "nights": 3,"currency": "EUR", "includeOffers": True})for hotel in client.dataset(run["defaultDatasetId"]).iterate_items():print(hotel["name"], hotel["pricePerNight"], hotel["currency"], hotel["cheapestOfferSite"])
Performance and limits
- Speed: about 1-3 seconds per result page of ~20 hotels. 600 hotels from 6 cities (100 each, in parallel) took 52 seconds; one city with 661 hotels took about 3 minutes. With booking sites, one extra request per hotel (42 hotels: 37 seconds).
- How many hotels: up to 1,000 per place, but Google's list usually ends earlier for a whole city (London: 661 hotels after 57 pages); the run summary then says "Google's list ended after N result pages". Google repeats some hotels across pages (removed). A search also stops after 3 pages in a row without a new hotel that has a price.
- Result pages staying on the search: for a plain place ("Barcelona", "hotels in Barcelona") later pages are asked for the place Google matched on page 1. Queries with more in them (a brand, "villas", "5 star", another name for the place) are paged as Google pages them and stop once Google's reported number of results has been read. If a later page comes back for another place, reports far more results than page 1 (Google dropped part of the query), or holds mostly hotels far outside page 1's area (more than 100 km, or 2.5 times page 1's spread), the search stops there with a free
list_driftedrow; nothing from that page is returned or charged. - Deep lists: use the filters, not words in the query. Google often drops qualifier words and brands from page 2 on, so "5 star hotels in Rome", "cheap hotels in Paris" or "Hilton London" usually return one page (about 18-20 hotels; in our tests "Hilton London" stopped after 18-31 of Google's 56) before the search stops. "Marriott Paris" happened to keep its brand for all 3 of its pages (38-39 hotels). For a long list, search the plain place ("Rome") and set Hotel class, Maximum price or Sort by instead: those are part of the search on every page. Category words such as "villas in Bali" or "hostels in Berlin" usually keep working on later pages.
- Dates: check-in from today to 365 days ahead, at most 30 nights. Google shows prices for about the next 11 months; for later dates most hotels have no price (skipped unless "Include hotels without a price" is on).
- Places Google can't match: Google never says "not found"; it shows hotels around a default place (the server's area or the Country). The Actor returns a free
not_foundrow when the query doesn't name the place Google shows and Google marks it as a fallback, or it has no map ID twice in a row. Queries that name the place ("Paris", "Hilton London") are always kept. A vague word Google does match to some real place is kept too, so checkresolvedLocation. - Landmarks: if "hotels near
- Filters (sort, rating, class, price, free cancellation) apply to place searches; a hotel name or link returns that hotel whatever they say. Property type applies to both.
- Amenities are Google's English labels whatever the language; free/paid variants (e.g. "Parking ($)") are known for result lists, while hotel names and links get the base labels ("Parking").
- Children: Google needs each child's age; some hotels have no price for families.
- Blocking: Google rarely blocks this endpoint from data-center IPs (no block in our tests). A blocked request is retried from another IP, and Google's temporary internal errors and transport glitches are retried too; nothing is solved or bypassed. If every search fails on our side, the run fails and only the Actor start is charged.
- Proxy: the default Apify Proxy (data center) is recommended. Residential and Google SERP proxy groups are not supported (they would cost more than the results). If your own proxy settings can't be used or don't connect, the run ends with a free
proxy_errorrow (searches that had not started yet are skipped) instead of going on without a proxy. Only connection failures count as a proxy problem: errors from Google itself are retried and reported as ours.
FAQ
Why are my prices different from what I see on Google? Google shows prices for your own country, currency and tax settings, and prices change by the minute. Compare displayedPrice and displayedPriceBasis, and remember that the Actor's requests come from Apify's data centers (mostly US).
Which booking sites are covered? Whatever Google lists for the hotel: online travel agencies (for example Booking.com, Expedia, Agoda, Hotels.com, Trip.com), metasearch sites and the hotel's own website. 29 sites for a big Barcelona hotel in our tests; fewer for small properties.
Does it return reviews or descriptions? No. It returns the rating and the number of reviews, not review texts, reviewer names, Google's descriptions or photo galleries (one thumbnail URL only).
Can I track the same hotels every day? Yes: put hotel names or Google Hotels links (or propertyToken values from an earlier run) in queries, use a relative check-in date such as "30 days", save it as a task and schedule it.
Can I compare dates? Yes, with searches (one entry per date range) in one run.
Hotels or vacation rentals? Google mixes both in its list. Use Property type to keep only one kind (the others are skipped and not charged).
What is propertyToken? Google Hotels' ID for the property. Paste it (or the googleHotelsUrl) into queries to fetch that hotel again. Google Hotels share links (/travel/hotels/s/...) can't be read directly: open them and paste the address they lead to.
Legal
This Actor reads price data that Google Hotels shows to any visitor without signing in: hotel names, prices, ratings, classes, amenities, locations and the prices of the booking sites Google aggregates (those sites' prices remain theirs). It does not log in, solve CAPTCHAs or collect personal data: no reviews or reviewer names, no phone numbers, no street address or website for vacation rentals (often private homes) and only an approximate position for them; names are scrubbed of e-mail addresses and phone numbers. Google's own descriptions and photo galleries are not output.
Google's terms of service restrict automated access to its services. Google's robots.txt disallows crawlers from /travel/search (the results page), /travel/entity, and the click-out paths /travel/clk and /travel/lodging/clk. The Actor does not load those pages: it calls the data endpoint behind the results page (/_/TravelFrontendUi/data/batchexecute), which robots.txt does not list, with the same source-path and referer the page itself sends, and it links to hotels as /travel/hotels/entity/..., a path the /travel/entity rule doesn't match. It is still the same data as the disallowed results page, and the Actor does not output Google's paid click-out links. You are responsible for using the Actor and the data lawfully and in line with the terms that apply to you, including the booking sites' rights in their prices. This is not legal advice.
Google and Google Hotels are trademarks of Google LLC; booking-site names are trademarks of their owners. This Actor is not affiliated with, endorsed by or sponsored by Google or any booking site.