Google Hotels Search Scraper avatar

Google Hotels Search Scraper

Pricing

from $1.75 / 1,000 hotel-listeds

Go to Apify Store
Google Hotels Search Scraper

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

BonCross API

Maintained by Community

Actor 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:

ActorWhat you give itWhat you get
Google Hotels Search Scraper (this one)A city, district or map boxThe hotels in that area, one price each
Google Hotels Prices ScraperOne hotelThe sellers Google compares for it, with a price from each
Google Hotels Reviews ScraperOne hotelIts 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 nameGoogle entity id and page URL
💰 Price per nightWhole-stay price
Pre-tax price where shown, and whether the price includes taxCurrency, dates and guests
⭐ Guest rating out of 5Review count
Star classProperty type: hotel or rental
📍 Latitude and longitudeWhich area and which pass returned it
Google's one-line blurb📈 Price change since the last run
Previous price and when it was readScrape 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.

  1. Create a free Apify account and open Google Hotels Search Scraper.
  2. Type one or more place names under Locations, such as Porto. For an exact boundary, draw a box under Custom areas.
  3. Pick check-in and check-out, the number of adults and a currency.
  4. Add filters if you want a narrower list, then press Start.
  5. 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:

  • freeCancellationOnly keeps hotels that offer a free-cancellation rate, and prices them at that rate.
  • specialOffersOnly keeps hotels Google marks as a deal for the dates. ecoCertifiedOnly keeps those with an eco-certification.
  • brands takes 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.
  • amenities takes 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

FieldNotes
locationsPlace names, one area each: a city, a town or a district.
customAreasA bounding box (south, west, north, east) or a point with radiusKm, each with a label.
textQueries, maxResultsPerTextQueryPhrases for Google's own ranking, and the cap per phrase (default 60, up to 500).
maxHotelsPerArea, maxItemsThe per-area cap and the run-wide cap. 0 means no cap on either.
checkIn, checkOutDates as YYYY-MM-DD.
checkInDaysAhead, nightsUsed when the dates are empty: default 30 days ahead for 2 nights.
adults1 to 8, default 2. Prices are quoted for this occupancy.
minRating, minReviewsRating and review-count floors. 0 is off.
minPricePerNight, maxPricePerNightPrice band per night, taxes and fees included, in your currency. A hotel with no price for the dates is dropped too.
hotelClassesStar classes to keep, such as [4, 5]. Properties with no class are dropped when this is set.
amenities, brandsGoogle's amenity and brand filters.
freeCancellationOnly, specialOffersOnly, ecoCertifiedOnlyGoogle's own switches. All off by default.
nameInclude, nameExcludeCase-insensitive pieces of a name to keep (["Hyatt", "Marriott"]) or drop (["hostel", "capsule"]).
onlyWithPriceDrop hotels Google shows without a price for the dates.
propertyTypesall (default), hotels or rentals.
sortByprice (default), rating, reviews or name.
currency, language, countryDefaults USD, en and us.
priceStoreName, onlyNewOrChangedThe price memory, and the switch that returns only hotels whose price moved.
tilesCoverage, 1 to 8, default 3. 1 is a single pass, 3 covers a city, 5 a metro area.
expandFactor, maxConcurrency, delayMsTuning. See below.

For developers

  • maxHotelsPerArea and maxResultsPerTextQuery are per target. maxItems is run-wide. A row reporting an area that couldn't be resolved isn't counted against maxItems and 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 (default 1.5, 0.1 to 10) widens or narrows the area resolved for a place name. 1 keeps Google's own framing, 1.5 takes in the suburbs, and below 1 tightens on the centre.
  • tiles above 3 makes more requests and takes longer. Raise it to 4 or 5 for a metro area.
  • maxConcurrency (default 32, 1 to 32) is how many requests run at once across the run. delayMs (default 0, up to 10,000) adds a pause before each request. The defaults are the settings we measured, and we'd keep them.
  • priceStoreName names 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 four previous… and priceChange… 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, checkout and checkinDaysAhead in lower case still work.
  • For customAreas, brands takes 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:

ColumnMeaning
id, url, entityId, entityUrlid 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, priceTotalTaxes and fees included, in any language and country.
pricesIncludeTaxtrue on a priced row, null on a hotel with no price for your dates.
pricePerNightExcludingTax, priceTotalExcludingTaxThe same prices before tax, filled where Google shows one: 110 of 120 rows on 2 October 2026.
stars, ratingstars is the official class where the property has one. rating is the guest score out of 5.
snippetGoogle's one-line blurb. Most hotels don't have one: it was on 12% of rows in a 100-hotel sample.
tileThe bounding box (south, west, north, east) of the pass that found the hotel.
previousPricePerNight, previousScrapedAt, priceChange, priceChangePctFilled 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.

SearchHotels returnedRun time
Osaka, first 10 hotels108 s (two runs)
Osaka, Kyoto and Tokyo, every hotel2,615 to 2,811 unique9 to 17 s (two runs)
10 cities, first 40 hotels each40020 s
70 cities on five continents, first 40 hotels each2,8002.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.

EventFree planStarterScaleBusiness
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.

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

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.