Google Hotels Search Scraper
Pricing
from $1.75 / 1,000 hotel-listeds
Google Hotels Search Scraper
Scrape Google Hotels prices for a whole city or map area. Just add place names or a bounding box, dates, guests and currency, and get every hotel with nightly and stay price, rating, review count, star class, coordinates and entity id. Track price changes between runs. $2.50 per 1,000 hotels.
Pricing
from $1.75 / 1,000 hotel-listeds
Rating
0.0
(0)
Developer
BonCross API
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
7 hours ago
Last modified
Categories
Share
What is Google Hotels Search Scraper?
One Google Hotels request shows you roughly 100 to 180 hotels, however big the city is. Google Hotels Search Scraper goes over the area in overlapping passes and removes the duplicates, which is how Osaka came back as 639 priced hotels in one run. Type a city, a district or a map box, set your dates, and you get one row per hotel with its price for that stay.
Why people choose it for market-wide pricing:
- Whole cities, quickly. Osaka, Kyoto and Tokyo together returned 2,615 to 2,811 unique hotels in 9 to 17 seconds on 2 October 2026.
- Google does most of the filtering. Price, rating, star class, amenities, brand, deals, eco-certification and free cancellation are sent to Google, and you get the matching hotels in place of a slice of its default list. In Osaka, asking for one brand returned 19 of its hotels where the unfiltered search showed 4.
- Tax is never a guess. Each priced row says whether the price includes tax, and it did on 120 of 120 rows across English, French, Japanese and German searches. 110 of them also had the pre-tax figure.
- A scheduled run can return only the hotels whose price moved. Unchanged hotels cost you nothing.
- $2.50 per 1,000 hotels on the Free plan, $1.75 on Business. Hotels your filters drop are free.
BonCross Verified means we tested this actor against the live site before release and kept the record:
- 41 of 41 live checks on its inputs and filters passed on 7 October 2026
- 6 areas run the same day in Portugal, Georgia, Vietnam, the US and Japan, the sixth unresolvable: 100 hotels, 1 error row
- Charges matched the rows
- An area Google cannot place gets a row saying why
There are three Google Hotels actors, and they do different jobs:
| Actor | What you give it | What you get |
|---|---|---|
| Google Hotels Search Scraper (this one) | A city, district or map box | The hotels in that area, one price each |
| Google Hotels Prices Scraper | One hotel | The sellers Google compares for it, with a price from each |
| Google Hotels Reviews Scraper | One hotel | Its guest reviews |
Start here when you don't have a hotel list yet. Each row has the entity id the other two accept.
What else it does:
- Prices any date range and 1 to 8 adults, in the currency you choose
- Returns the nightly price and the whole-stay price, plus the pre-tax price wherever Google shows one
- Sorts by price, rating or review count using Google's own sorts, which means a price sort finds the cheapest hotels Google has for those dates
- Keeps hotels, vacation rentals or both
- Adds each hotel's price change since your last run, in money and per cent
- Answers a phrase such as "hostels in Lisbon" with Google's ranking for it, checked with the language set to English, Japanese and German
- Writes a row saying why when an area can't be found
What data do you get for each hotel?
| 🏨 Hotel name | Google entity id and page URL |
| 💰 Price per night | Whole-stay price |
| Pre-tax price where shown, and whether the price includes tax | Currency, dates and guests |
| ⭐ Guest rating out of 5 | Review count |
| Star class | Property type: hotel or rental |
| 📍 Latitude and longitude | Which area and which pass returned it |
| Google's one-line blurb | 📈 Price change since the last run |
| Previous price and when it was read | Scrape timestamp |
| ☎️ Phone, website and Place ID (text queries) | Maps amenities and categories (text queries) |
How to scrape Google Hotels prices for a city
There's nothing to install and no code to write. The input is a form, and a city's hotels arrive as a spreadsheet.
- Create a free Apify account and open Google Hotels Search Scraper.
- Type one or more place names under Locations, such as Porto. For an exact boundary, draw a box under Custom areas.
- Pick check-in and check-out, the number of adults and a currency.
- Add filters if you want a narrower list, then press Start.
- Download the hotels as Excel, CSV, JSON, XML or HTML.
⬇️ Input
A place name and a stay are enough. Leave the dates empty and the run prices two nights starting 30 days from today.
You have two kinds of limit. "Max hotels per area" and "Max results per text query" apply to each target separately: ten areas at 50 each returns 500. "Maximum results for the whole run" caps the total, and nothing past it is fetched or charged for.
A city for fixed dates
{"locations": ["Porto"],"checkIn": "2026-11-13","checkOut": "2026-11-15","adults": 2,"currency": "USD","language": "en","country": "pt","tiles": 3}
Setting Country to the hotel's own market usually returns the fullest list. One Tokyo box returned 160 hotels with country: "jp" and 102 with country: "us".
A scheduled monitor that reports price changes
Leave the dates empty and the run prices a rolling window. A daily schedule then always looks the same distance ahead. With a price store, only hotels whose price moved are returned and charged.
{"locations": ["Aspen, Colorado", "Porto"],"checkInDaysAhead": 30,"nights": 2,"adults": 2,"currency": "USD","priceStoreName": "aspen-porto-30-days-ahead","onlyNewOrChanged": true}
An exact map box, filtered
{"customAreas": [{ "label": "Porto centre", "south": 41.122, "west": -8.627, "north": 41.143, "east": -8.586 }],"checkIn": "2026-11-13","checkOut": "2026-11-15","tiles": 2,"minRating": 4,"minReviews": 100,"hotelClasses": [4, 5],"amenities": ["freeWifi", "pool"],"freeCancellationOnly": true,"maxPricePerNight": 400,"currency": "USD","sortBy": "price"}
Run on 7 October 2026, this box returned four and five star hotels from $75 a night, cheapest first.
Google's ranking for a phrase
{"textQueries": ["hostels in Lisbon", "ryokan in Kyoto"],"maxResultsPerTextQuery": 40,"checkIn": "2026-11-13","checkOut": "2026-11-15"}
Text-query rows give you Google's ranking for the phrase and the Maps details (Place ID, categories, address, phone, website, amenities). They have no dated price, which means the price limits and "Only hotels with a price" don't apply to them.
Which filters Google applies, and which are applied to the rows
Google applies these itself, and returns the hotels that match: the price, rating and review-count sorts, the price limits, a guest-rating floor of 3.5 or more, star classes, amenities, brands, special offers, eco-certification, free cancellation and rentals-only. Sorted by price (the default), you get the cheapest hotels Google has for your dates. "minRating": 4 returns more hotels rated 4 and up than an unfiltered search holds.
The rest are applied to each row Google returns: rating floors below 3.5 or between Google's steps, the review-count floor, the name filters, hotels-only and the name sort.
A few details:
freeCancellationOnlykeeps hotels that offer a free-cancellation rate, and prices them at that rate.specialOffersOnlykeeps hotels Google marks as a deal for the dates.ecoCertifiedOnlykeeps those with an eco-certification.brandstakes chain or brand names such as["Hilton", "Marriott"]and matches them against the brands Google lists for each place. An exact name wins. Otherwise any brand containing the text matches, and "Marriott" also takes Courtyard by Marriott.amenitiestakes Google's list, and a hotel must have all of the ones you tick:freeWifi,freeBreakfast,restaurant,bar,childFriendly,petFriendly,freeParking,parking,evCharger,roomService,fitnessCentre,spa,pool,indoorPool,outdoorPool,airConditioned,wheelchairAccessible,beachAccess,allInclusive,airportShuttle,casino,hotTub,onsen,publicBath,openAirBath,privateBath,sauna.
All inputs
| Field | Notes |
|---|---|
locations | Place names, one area each: a city, a town or a district. |
customAreas | A bounding box (south, west, north, east) or a point with radiusKm, each with a label. |
textQueries, maxResultsPerTextQuery | Phrases for Google's own ranking, and the cap per phrase (default 60, up to 500). |
maxHotelsPerArea, maxItems | The per-area cap and the run-wide cap. 0 means no cap on either. |
checkIn, checkOut | Dates as YYYY-MM-DD. |
checkInDaysAhead, nights | Used when the dates are empty: default 30 days ahead for 2 nights. |
adults | 1 to 8, default 2. Prices are quoted for this occupancy. |
minRating, minReviews | Rating and review-count floors. 0 is off. |
minPricePerNight, maxPricePerNight | Price band per night, taxes and fees included, in your currency. A hotel with no price for the dates is dropped too. |
hotelClasses | Star classes to keep, such as [4, 5]. Properties with no class are dropped when this is set. |
amenities, brands | Google's amenity and brand filters. |
freeCancellationOnly, specialOffersOnly, ecoCertifiedOnly | Google's own switches. All off by default. |
nameInclude, nameExclude | Case-insensitive pieces of a name to keep (["Hyatt", "Marriott"]) or drop (["hostel", "capsule"]). |
onlyWithPrice | Drop hotels Google shows without a price for the dates. |
propertyTypes | all (default), hotels or rentals. |
sortBy | price (default), rating, reviews or name. |
currency, language, country | Defaults USD, en and us. |
priceStoreName, onlyNewOrChanged | The price memory, and the switch that returns only hotels whose price moved. |
tiles | Coverage, 1 to 8, default 3. 1 is a single pass, 3 covers a city, 5 a metro area. |
expandFactor, maxConcurrency, delayMs | Tuning. See below. |
For developers
maxHotelsPerAreaandmaxResultsPerTextQueryare per target.maxItemsis run-wide. A row reporting an area that couldn't be resolved isn't counted againstmaxItemsand isn't charged.- A text query stops after three requests in a row that find no new lodging place, and at three times the requests its limit needs. A phrase that isn't about lodging ends quickly.
expandFactor(default1.5, 0.1 to 10) widens or narrows the area resolved for a place name.1keeps Google's own framing,1.5takes in the suburbs, and below1tightens on the centre.tilesabove 3 makes more requests and takes longer. Raise it to 4 or 5 for a metro area.maxConcurrency(default32, 1 to 32) is how many requests run at once across the run.delayMs(default0, up to 10,000) adds a pause before each request. The defaults are the settings we measured, and we'd keep them.priceStoreNamenames a key-value store that remembers each hotel's price for the same dates, occupancy and currency. From the second run on, rows gain the fourprevious…andpriceChange…columns.- If Apify moves a run to another server, or it restarts, it carries on where it stopped. No hotel is returned or charged twice.
checkin,checkoutandcheckinDaysAheadin lower case still work.- For
customAreas,brandstakes Google's numeric brand ids, not names.
⬆️ Output
You get one record per hotel. This one is from the Porto example above, run on 7 October 2026.
{"id": "ChoIgb3p6s3jrr2nARoNL2cvMTFiOGMyenh6MBAB","url": "https://www.google.com/travel/hotels/entity/ChoIgb3p6s3jrr2nARoNL2cvMTFiOGMyenh6MBAB","entityId": "ChoIgb3p6s3jrr2nARoNL2cvMTFiOGMyenh6MBAB","entityUrl": "https://www.google.com/travel/hotels/entity/ChoIgb3p6s3jrr2nARoNL2cvMTFiOGMyenh6MBAB","name": "O2 Hostel","stars": 2,"rating": 4.2,"ratingScale": 5,"reviewCount": 492,"lat": 41.147064199999996,"lng": -8.5965319,"pricePerNight": 30,"pricePerNightText": "US$30","pricePerNightExcludingTax": 22,"priceTotal": 60,"priceTotalText": "US$60","priceTotalExcludingTax": 44,"pricesIncludeTax": true,"currency": "USD","checkIn": "2026-11-13","checkOut": "2026-11-15","nights": 2,"adults": 2,"snippet": null,"propertyType": "hotel","area": "Porto","tile": "41.122076,-8.62698,41.142671,-8.586338","previousPricePerNight": null,"previousScrapedAt": null,"priceChange": null,"priceChangePct": null,"scrapedAt": "2026-10-07T20:25:52.402Z"}
Some columns need a word:
| Column | Meaning |
|---|---|
id, url, entityId, entityUrl | id and url repeat the entity id and its page. The entity id is what the Prices and Reviews actors take, which is why it keeps a column of that name. |
pricePerNight, priceTotal | Taxes and fees included, in any language and country. |
pricesIncludeTax | true on a priced row, null on a hotel with no price for your dates. |
pricePerNightExcludingTax, priceTotalExcludingTax | The same prices before tax, filled where Google shows one: 110 of 120 rows on 2 October 2026. |
stars, rating | stars is the official class where the property has one. rating is the guest score out of 5. |
snippet | Google's one-line blurb. Most hotels don't have one: it was on 12% of rows in a 100-hotel sample. |
tile | The bounding box (south, west, north, east) of the pass that found the hotel. |
previousPricePerNight, previousScrapedAt, priceChange, priceChangePct | Filled only with a price memory store, from the second run on. |
Setting a price limit leaves out hotels with no price for your dates. In a sort, unpriced hotels come last.
How many hotels can you get, and how fast?
These are whole runs on Apify from 2 October 2026: 2 adults, 2 nights, USD, coverage 3.
| Search | Hotels returned | Run time |
|---|---|---|
| Osaka, first 10 hotels | 10 | 8 s (two runs) |
| Osaka, Kyoto and Tokyo, every hotel | 2,615 to 2,811 unique | 9 to 17 s (two runs) |
| 10 cities, first 40 hotels each | 400 | 20 s |
| 70 cities on five continents, first 40 hotels each | 2,800 | 2.6 to 3 min |
A run covers about 25 areas a minute at the default coverage. That's roughly 1,400 areas in the default one-hour run.
Most of a run is spent waiting for Google, and its answer time changes from minute to minute. The same search can take two or three times as long in a slow minute.
Coverage recovers most of a city. It isn't a provably complete list, because Google ranks and truncates what it returns for any viewport. Raising Coverage to 4 or 5, or drawing a wider box, finds more.
How much does it cost to search Google Hotels?
You pay per hotel that reaches your dataset, plus two small fixed fees.
| Event | Free plan | Starter | Scale | Business |
|---|---|---|---|---|
actor-start, per run | $0.002 | $0.002 | $0.002 | $0.002 |
area-searched, per resolved area, however many passes it takes | $0.005 | $0.005 | $0.005 | $0.005 |
query-checked, per text query Google answered that returns no hotel | $0.0005 | $0.0005 | $0.0005 | $0.0005 |
hotel-listed, per hotel returned | $0.0025 | $0.00225 | $0.002 | $0.00175 |
Enterprise plans pay the Business price.
$2.50 per 1,000 hotels on the Free plan, $1.75 on Business. That's the whole price: proxy usage and platform usage are included.
Hotels dropped by your filters are free, and so are unchanged hotels when "Only new or changed prices" is on. A text query that returns no hotel at all is billed the $0.0005 query-checked fee once. A query that couldn't be searched is free.
- A whole city. Osaka returned 639 hotels: $0.002 + $0.005 + 639 × $0.0025 = $1.60 ($1.13 on Business). A city of 600 to 1,500 hotels costs $1.51 to $3.76 on the Free plan ($1.06 to $2.63 on Business).
- A daily district monitor. For a district of about 150 hotels, day one is $0.002 + $0.005 + 150 × $0.0025 = $0.38 ($0.27 on Business). With a price store, a day on which 30 prices moved costs $0.002 + $0.005 + 30 × $0.0025 = $0.08 ($0.06 on Business).
The $5 of credits that Apify's Free plan includes each month buys about 1,950 hotels here: thirteen district-sized runs of 150.
Limitations
- The price is Google's displayed price per night for the adults you set. It doesn't tell you who is selling at that price. For the price from each seller, pass the entity id to Google Hotels Prices Scraper.
- Occupancy is adults only here. Children and several rooms are handled by Google Hotels Prices Scraper.
- Google reshuffles which hotels an area search surfaces. Two identical runs can return a noticeably different selection. Raise Coverage for a fuller list.
- The box Google resolves for a place name can shift slightly between runs. For a monitor that stays put, draw a custom area.
- Area rows don't list a hotel's amenities or description. The amenities filter narrows the set, but the list itself appears only on text-query rows.
- Google's guest-rating filter has three steps (3.5+, 4.0+, 4.5+). A floor below 3.5, the part of a floor between two steps and the review-count floor trim the rows Google returns. They don't widen the search.
- Brands, special offers and eco-certification narrow hotels only. While one is set, vacation rentals aren't added, and rows have no brand, deal or eco column.
- Pre-tax prices appear only where Google shows them.
- Text-query rows have no dated price.
FAQ
Do I need proxies or a Google account to scrape Google Hotels?
Neither. There's nothing to log in to, and proxy usage is included in the price with nothing to set up.
How many hotels will I get for my city?
As many as Google shows across the passes. Osaka at coverage 3 gave 639. For a wider metro area, raise Coverage to 4 or 5 or draw a bigger custom box.
Why do some hotels have no price?
Google won't price them for those dates, usually because they're sold out or can't be booked through Google. Switch on "Only hotels with a price" to drop them.
Why did the same search return different hotels the second time?
Google reshuffles which hotels it surfaces for an area, and the effect is large on a small capped run. Run with a higher Coverage and no per-area cap if you need the list to be stable, and compare runs on the entity id.
How do I track a city's prices day by day?
Leave the dates empty, set "Check-in days ahead", name a price memory store and switch on "Only new or changed prices". Put the run on an Apify Schedule. Each run then returns the hotels whose price moved, with the old price and the change.
Which market and currency are the prices for?
The ones you set. Currency takes any ISO code, and the numbers arrive in it. Country and Language choose the Google market. The domestic market usually lists more local properties and sometimes different prices.
Can I search by phrase, in another language?
Text queries take any phrase Google Maps understands, and we've checked them with Language set to English, Japanese and German. On 7 October 2026 two phrases run with Japanese settings returned 30 hotels between them, and two run with German settings returned 16. Rows from a phrase have no dated price.
Is scraping Google Hotels legal?
The actor reads only what Google serves to any logged-out visitor, and it collects hotel listings and prices, not personal data. Scraping publicly available data is generally legal, but you're responsible for complying with Google's terms and applicable law in how you use it.
Run it on a schedule, or from your own code
A daily schedule with a price store is the setup we'd recommend for rate shopping. Each run reports who moved overnight, and a webhook can push that to Slack or a Google Sheet through Apify's integrations.
From code, POST https://api.apify.com/v2/acts/boncross~google-hotels-search/run-sync-get-dataset-items with the input JSON as the body returns the hotels in one call for short runs. Longer ones use the standard run endpoints, or the apify-client package for Node.js or Python.
AI agents can call it through the Apify MCP server at mcp.apify.com, where it appears as the tool google-hotels-search. An agent can ask for a city and dates, then hand the entity ids it gets to the Prices actor.
More from BonCross
- Accor Hotel Details Scraper: Full Accor hotel records.
- Agoda Search Scraper: Agoda search results for any destination and dates.
- Booking.com Hotel Search Scraper: Every hotel Booking.com is selling for a destination and your dates.
- Expedia Hotel Search Scraper: Every hotel Expedia and Hotels.com list for a destination and your dates.
- Google Maps Reviews Scraper: Google Maps reviews for any place using URLs, Place IDs or names.
- Tripadvisor Place Details Scraper: The full Tripadvisor record for any hotel, restaurant or attraction.
Your feedback
Is a hotel missing from an area you know well, or a price that doesn't match what Google shows? Open an issue on the Issues tab in Apify Console and give us the place and dates. We read every one and reply there.