# Google Hotels Scraper (`lergassy/google-hotels-scraper`) Actor

Scrape Google Hotels by city and dates: hotels with nightly and total price, taxes, rating, review count, star class, amenities, coordinates, photos and booking link, plus per-site offers and guest reviews. Export data, run via API, schedule runs, or integrate with AI workflows.

- **URL**: https://apify.com/lergassy/google-hotels-scraper.md
- **Developed by:** [Matvey](https://apify.com/lergassy) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $2.10 / 1,000 hotels

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

**Google Hotels Scraper** extracts hotels from **Google Hotels** for any place and any dates — the **nightly price and the stay total with taxes**, the guest **rating and review count**, star class, property type, **amenities**, coordinates, photos, check-in and check-out times, the Google Hotels page and the **booking link** — and, on request, every **booking site's offer** for a hotel, its full address and phone, and the **guest reviews** Google aggregates from Tripadvisor, Trip.com and the booking sites. Google shows 20 hotels and stops; this Actor walks Google's own sort orders, star classes and price bands and de-duplicates by hotel, so one search for a city returns **well over a hundred properties** instead of twenty. **Pure HTTP, no browser, no login, no API key** — a search of 150 hotels takes about 17 seconds.

![Google Hotels Scraper output: hotels with star class, rating, review count, nightly price, stay total and amenities](https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/google-hotels-scraper/google-hotels-scraper-output-table.png)

Paste a city, pick dates, click Start, and download JSON, CSV or Excel — or pull the rows through the Apify API into Google Sheets, n8n, Make, Zapier, a database or an AI agent.

### What is Google Hotels Scraper?

Google Hotels is the price comparison inside Google Travel: for a place and a stay it lists the properties, the cheapest rate it found across Booking.com, Expedia, Agoda, Hotels.com, Trip.com, the hotel's own site and dozens of smaller sellers, the aggregate guest rating, and the amenities. There is no official **Google Hotels API**. This Actor is the **Google Hotels API alternative**: it reads the same JSON endpoint the Google Hotels page itself calls, plus the server-rendered hotel page, and turns them into flat rows you can sort, filter and join.

It answers the questions a revenue manager, an OTA analyst or a travel-data team actually asks:

- What does every hotel in Lisbon cost for the first weekend of October, and how does that compare with last month?
- Which 4- and 5-star properties in Ubud are rated 4.5 or better, and what is the cheapest nightly rate among them?
- Which booking sites sell a given hotel, at what total, and where is the official site's price against Booking.com?
- What do guests praise and complain about — service, location, dining, cleanliness — and how many say so?

Three modes, one row shape:

| Mode | You give | You get |
|---|---|---|
| **Search** | places, check-in, check-out, guests | hotels with price for that stay, rating, reviews, class, amenities, location, photos, booking link |
| **Search + hotel pages** (add-on) | the same, with *read each hotel's page* on | everything above plus every booking site's offer with a deep link, the full amenity list, address and phone, review scores per source, guest reviews |
| **Hotel pages** | Google Hotels URLs or entity ids | one row per hotel with offers, reviews and full details — no search |

### What data can Google Hotels Scraper extract?

Every hotel row carries these fields. Nothing is invented: a field Google did not show for a property is empty rather than guessed.

| Field | Example | Notes |
|---|---|---|
| `name` | Alaya Resort Ubud | |
| `hotelClass`, `hotelClassLabel` | 5, "5-star hotel" | empty for unrated properties |
| `propertyType` | resort hotel | hotel, villa, bed and breakfast, hostel, apartment, guest house … |
| `rating`, `reviewCount` | 4.7, 4006 | Google's aggregate, 5-point scale |
| `pricePerNight`, `pricePerNightDisplay` | 340.29, "$340" | the cheapest rate Google found for the searched stay, taxes included, averaged per night |
| `totalPrice`, `totalPriceDisplay` | 680.59, "$681" | the whole stay |
| `priceBeforeTaxes`, `taxesAndFees` | 562.45, 118.13 | when Google itemises them |
| `currency` | USD | any code Google supports |
| `checkIn`, `checkOut`, `nights`, `adults` | 2026-10-10, 2026-10-12, 2, 2 | what the price was quoted for |
| `description` | Polished rooms in a chic getaway offering a spa… | Google's one-line summary |
| `address`, `phone`, `website` | Jl. Hanoman, Ubud…, +62 361 972200, alayahotels.com | address and phone come with the hotel page; the website usually comes with search |
| `country`, `latitude`, `longitude` | ID, -8.5188, 115.2635 | |
| `checkInTime`, `checkOutTime` | 3:00 PM, 12:00 PM | |
| `amenities`, `amenityIds` | \["Free Wi-Fi", "Outdoor pool", "Spa"], \[29, 22, 26] | names for the ids Google uses; the hotel page adds the full list with free/paid qualifiers |
| `ratingHistogram` | {stars5: 3272, stars4: 518, …} | review counts per star |
| `reviewTopics` | Service 705 mentions, 667 positive, 28 negative | what guests write about |
| `nearbyPlaces` | Sacred Monkey Forest Sanctuary, 7 min | landmarks, transport, airport with travel time |
| `thumbnail`, `photos` | image URLs | |
| `entityId`, `placeId`, `hotelUrl`, `bookingUrl` | ChgI…, 0x2dd2…, google.com/travel/hotels/entity/…, google.com/travel/clk/… | the booking link goes to the cheapest seller for the searched stay |
| `location`, `searchRank` | Ubud, Bali, 1 | the place you searched and the row's position |
| `offers[]` | Booking.com $264, Vio.com $166, Expedia $233 … | hotel page: seller, stay total, per night, dates quoted, deep link, official-site flag |
| `cheapestOfferSeller`, `cheapestOfferTotal`, `cheapestOfferPerNight` | Vio.com, 166.33, 166.33 | the lowest of the offers |
| `reviewSources[]` | Tripadvisor 4.8 (1,490), Trip.com 4.7 (104) | rating and count per source Google aggregates |
| `reviews[]` | source, author, date, rating, text, link | the reviews Google renders on the hotel page |

### Beyond Google's 20 results

Google Hotels returns 20 properties per request, and its "next page" is the same request with a different filter — there is no offset to walk. Other scrapers stop at those 20, or page blindly and return the same hotels again.

This Actor reads the way Google itself lets you explore: it asks for the same place sorted by relevance, by lowest price, by highest rating and by most reviewed, then per star class, then under a few price caps, and keeps every hotel once. Measured on Ubud, Bali on 14 September 2026: **197 distinct hotels from 15 requests**, against 20 from the first request. Set **Hotels per place** to what you need; the walk stops when the count is reached or when four facets in a row bring nothing new, so a small town does not burn requests looking for hotels it does not have.

The price on each row is still Google's own cheapest rate for your dates — the facet walk only changes which hotels come back, never what Google says they cost.

### How much does it cost to scrape Google Hotels?

The Actor is priced **per hotel row**, with an add-on per hotel page read. There is **no start fee**, and rows that failed or came back empty are never charged.

| Event | Price | What it buys |
|---|---|---|
| Hotel | **$3.00 per 1,000** | one hotel with price, rating, class, amenities, location, photos, booking link |
| Hotel page read (add-on) | **$8.00 per 1,000** | that hotel's offers from every booking site, full amenities, address, phone, review sources, guest reviews |

Two hundred hotels for a city cost $0.60. Reading the page of the fifty you shortlist adds $0.40. There is no residential proxy and no browser to pay for: the Actor's own platform usage is a fraction of a cent per run. Bronze, Silver and Gold plans get 10 %, 20 % and 30 % off.

The **free plan** includes $5 of usage every month — about 1,600 hotel rows, or a full city every day of the month.

### How to scrape Google Hotels

1. Open the Actor and type the **place** the way you would in Google Hotels: a city, a district, a landmark. One per line for several.
2. Set **check-in and check-out**. Leave them empty for a two-night stay 30 days out — the Actor never searches a date that has passed, even from a saved task.
3. Pick the **currency** and how many **hotels per place** you want. Twenty is one Google page; a hundred or more is what Google would never show you at once.
4. Optionally filter — **star class**, **minimum rating**, **maximum price per night**, **pool** — and turn on **read each hotel's page** to get every booking site's offer and the guest reviews.
5. Click **Start**. Results appear in the dataset as the run goes; export them as JSON, CSV or Excel, or read them through the API.

### ⬇️ Input

![Google Hotels Scraper input form: place, check-in and check-out dates, adults, hotels per place, currency and filters](https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/google-hotels-scraper/google-hotels-scraper-input-form.png)

#### Hotels for a city and dates

```json
{
  "locations": ["Ubud, Bali"],
  "checkIn": "2026-10-10",
  "checkOut": "2026-10-12",
  "adults": 2,
  "currency": "USD",
  "maxHotelsPerLocation": 100
}
```

#### Shortlist with filters

```json
{
  "locations": ["Lisbon", "Porto"],
  "checkIn": "2026-11-06",
  "checkOut": "2026-11-08",
  "hotelClass": ["4", "5"],
  "minRating": "4.5",
  "maxPricePerNight": 250,
  "sortBy": "lowest_price",
  "maxHotelsPerLocation": 60
}
```

Filters are sent to Google where it supports them and checked again on every row, so a 3-star property cannot slip into a 4–5-star shortlist through a ranking quirk.

#### Offers from every booking site, plus reviews

```json
{
  "locations": ["Shibuya, Tokyo"],
  "checkIn": "2026-12-20",
  "checkOut": "2026-12-23",
  "maxHotelsPerLocation": 30,
  "includeOffers": true,
  "maxOfferLookups": 30,
  "includeReviews": true,
  "maxReviews": 10
}
```

#### Hotel pages by URL

```json
{
  "hotelUrls": [
    "https://www.google.com/travel/hotels/entity/ChgI56yqtNfw86kxGgwvZy8xMXpicXFianMQAQ",
    "ChkIjJ2ht8Gcu_h5Gg0vZy8xMWM1cnRwc3lmEAE"
  ],
  "includeReviews": true
}
```

Entity ids come from an earlier run's `entityId` column, so a daily price monitor for a fixed set of hotels needs no search at all.

#### Every input field

| Field | Default | Meaning |
|---|---|---|
| `locations` | `["Ubud, Bali"]` | places to search, one per line |
| `checkIn`, `checkOut` | 30 days out, 2 nights | `YYYY-MM-DD` |
| `adults` | 2 | guests in one room, 1–8 |
| `maxHotelsPerLocation` | 40 | how deep to go per place, up to 500 |
| `currency` | USD | any ISO code |
| `sortBy` | relevance | `relevance`, `lowest_price`, `highest_rating`, `most_reviewed` — the first facet read and the `searchRank` order |
| `hotelClass` | any | keep only these star classes |
| `minRating` | any | 3.5, 4 or 4.5 |
| `maxPricePerNight` | none | in the output currency |
| `poolOnly` | false | only hotels with a pool |
| `includeOffers` | false | read each hotel's page for offers, full amenities, address, phone, review sources ($) |
| `maxOfferLookups` | 20 | cap on pages read per run |
| `includeReviews` | false | include guest reviews from the hotel page |
| `maxReviews` | 10 | per hotel |
| `hotelUrls` | — | Google Hotels URLs or entity ids to read directly |
| `language`, `market` | en, us | language of labels; country Google prices for |
| `proxyConfiguration` | Apify datacenter | residential only if a run reports consent pages |

### ⬆️ Output

One row per hotel. Error rows carry `type: "error"` and an explanation, and are never charged.

```json
{
  "type": "hotel",
  "name": "Alaya Resort Ubud",
  "hotelClass": 5,
  "hotelClassLabel": "5-star hotel",
  "propertyType": "resort hotel",
  "rating": 4.7,
  "reviewCount": 4006,
  "pricePerNight": 340.29,
  "pricePerNightDisplay": "$340",
  "totalPrice": 680.59,
  "totalPriceDisplay": "$681",
  "priceBeforeTaxes": 562.45,
  "taxesAndFees": 118.13,
  "currency": "USD",
  "checkIn": "2026-10-10",
  "checkOut": "2026-10-12",
  "nights": 2,
  "adults": 2,
  "description": "Polished rooms in a chic getaway offering a spa, a low-key bar & a bright restaurant.",
  "website": "https://alayahotels.com/alaya-resort-ubud/",
  "country": "ID",
  "latitude": -8.5187697,
  "longitude": 115.263528,
  "checkInTime": "3:00 PM",
  "checkOutTime": "12:00 PM",
  "amenities": ["Air conditioning", "Bar", "Free breakfast", "Fitness center", "Free parking", "Pet-friendly", "Outdoor pool", "Restaurant", "Spa", "Free Wi-Fi"],
  "amenityIds": [2, 4, 6, 8, 16, 18, 22, 23, 26, 29],
  "ratingHistogram": { "stars5": 3272, "stars4": 518, "stars3": 114, "stars2": 42, "stars1": 60 },
  "reviewTopics": [
    { "topic": "Service", "mentions": 705, "positive": 667, "negative": 28, "score": 0.81 },
    { "topic": "Location", "mentions": 423, "positive": 384, "negative": 11, "score": 0.74 }
  ],
  "nearbyPlaces": [
    { "name": "Sacred Monkey Forest Sanctuary", "travelTime": "7 min" },
    { "name": "I Gusti Ngurah Rai International Airport", "travelTime": "1 hr 8 min" }
  ],
  "thumbnail": "https://lh3.googleusercontent.com/…",
  "photos": ["https://lh3.googleusercontent.com/…"],
  "entityId": "ChgI56yqtNfw86kxGgwvZy8xMXpicXFianMQAQ",
  "placeId": "0x2dd23d6c35a395c7:0x3153cf85768a9667",
  "hotelUrl": "https://www.google.com/travel/hotels/entity/ChgI56yqtNfw86kxGgwvZy8xMXpicXFianMQAQ",
  "bookingUrl": "https://www.google.com/travel/clk/hi?qid=…",
  "location": "Ubud, Bali",
  "searchRank": 1,
  "scrapedAt": "2026-09-14T13:14:01.199Z"
}
```

#### With the hotel page read

```json
{
  "address": "Jl. Raya Sanggingan, Ubud, Kecamatan Ubud, Kabupaten Gianyar, Bali 80571, Indonesia",
  "phone": "+62 361 974330",
  "offers": [
    { "seller": "Vio.com", "totalPrice": 166.33, "totalPriceDisplay": "$166", "pricePerNight": 166.33, "checkIn": "2026-09-28", "checkOut": "2026-09-29", "nights": 1, "bookingUrl": "https://www.vio.com/…", "isOfficialSite": false },
    { "seller": "Pita Maha Resort & Spa", "totalPrice": 264.08, "totalPriceDisplay": "$264", "pricePerNight": 264.08, "checkIn": "2026-09-28", "checkOut": "2026-09-29", "nights": 1, "bookingUrl": "https://pitamaha.reserveonline.id/…", "isOfficialSite": false }
  ],
  "offersCheckIn": "2026-09-28",
  "offersCheckOut": "2026-09-29",
  "cheapestOfferSeller": "Vio.com",
  "cheapestOfferTotal": 166.33,
  "reviewSources": [
    { "source": "Tripadvisor", "rating": 4.8, "ratingScale": 5, "reviewCount": 1490 },
    { "source": "Trip.com", "rating": 4.7, "ratingScale": 5, "reviewCount": 104 }
  ],
  "reviews": [
    { "source": "Tripadvisor", "author": "N8293ABtammyh", "date": "2 weeks ago", "rating": 5, "ratingScale": 5, "text": "We had an absolutely wonderful stay…", "url": "https://www.tripadvisor.com/…" }
  ],
  "detailsFetched": true
}
```

One thing to know about offers, stated plainly because it is easy to misread: **Google's hotel page quotes every booking site for the stay Google picks by default — about two weeks out — and ignores the dates in the address bar.** The Actor reads those dates back and stamps them on each offer (`offersCheckIn`, `offersCheckOut`), so the seller list, the deep links and the relative order of sellers are exact, but the offer totals are for that default stay. **The price for your searched dates is `pricePerNight` / `totalPrice` on the same row** — Google's cheapest rate across the same sellers — and `bookingUrl` opens that seller for your dates.

The dataset has three table views: **Hotels**, **Offers per booking site** (one line per seller) and **Guest reviews** (one line per review).

### Use cases for Google Hotels data

#### Rate shopping and revenue management

Run the same city every morning and diff `pricePerNight` per `entityId`: who dropped, who raised, where you sit against the compset for the next weekend. The facet walk means the compset is the whole market, not the twenty hotels Google felt like showing.

#### OTA and metasearch analysis

With the hotel page read, `offers` tells you which sellers list a property and at what total. Count how often the official site is the cheapest, which OTAs undercut whom, and where a hotel is missing from a channel entirely.

#### Market research and site selection

Class, price band, rating and amenity mix for every property in a district, with coordinates for a map. Compare Shibuya with Shinjuku, or Ubud with Seminyak, in one run.

#### Guest-experience research

`reviewTopics` gives you what guests talk about and how it splits positive against negative, for every hotel in a city, without reading a review. `reviews` gives you the text when you do want to read.

#### Travel products and AI agents

Flat rows with a stable `entityId`, a booking link and a per-night price are what a trip planner, a price-alert bot or an agent answering "find me a 4-star under $150 near the station" needs. The Actor runs from the Apify API and through the Apify MCP server.

### Integrations

- **API**: start a run with `POST https://api.apify.com/v2/acts/lergassy~google-hotels-scraper/runs?token=…` and read `…/datasets/{id}/items?format=csv`.
- **Clients**: `apify-client` for Python and JavaScript wrap the same calls.
- **Google Sheets, n8n, Make, Zapier**: use the Apify integration; the flat row shape needs no transformation.
- **Webhooks**: fire on run finish to pull the dataset into your own system.
- **MCP**: the Actor is callable as a tool through the Apify MCP server, so an AI agent can search hotels and read prices in a conversation.
- **Schedules**: a daily task with a fixed `hotelUrls` list is a price monitor for your own properties and competitors.

```python
from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("lergassy/google-hotels-scraper").call(run_input={
    "locations": ["Lisbon"], "checkIn": "2026-11-06", "checkOut": "2026-11-08",
    "hotelClass": ["4", "5"], "maxHotelsPerLocation": 100,
})
for hotel in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(hotel["name"], hotel["pricePerNight"], hotel["rating"])
```

### 🤖 For AI agents and LLM apps

Inputs that matter: `locations` (list of place strings), `checkIn` and `checkOut` (`YYYY-MM-DD`), `maxHotelsPerLocation` (integer), `currency` (ISO code), optional `hotelClass` (list of "1"–"5"), `minRating` ("3.5" | "4" | "4.5"), `maxPricePerNight` (number), `includeOffers` (boolean, costs one page read per hotel), `hotelUrls` (list of Google Hotels URLs or entity ids).

Output: one JSON object per hotel with `name`, `hotelClass`, `rating`, `reviewCount`, `pricePerNight`, `totalPrice`, `currency`, `checkIn`, `checkOut`, `amenities`, `latitude`, `longitude`, `address`, `hotelUrl`, `bookingUrl`, `entityId`; with `includeOffers`, also `offers[]` (`seller`, `totalPrice`, `bookingUrl`), `reviewSources[]` and `reviews[]`. Rows with `type: "error"` explain what to change. Sort or filter on the numeric fields directly; use `entityId` to refer to the same hotel across runs.

### Limits, honestly

- **Search returns what Google shows for the place.** Google decides which properties belong to "Ubud, Bali"; the facet walk enlarges that set but cannot add a hotel Google does not list there.
- **Offers on the hotel page are for Google's default stay**, not the searched dates — see the output section. The searched stay's cheapest price is on every row regardless.
- **Address and phone** arrive with the hotel page; Google includes them in search results only sometimes.
- **Amenities from search** are the ids Google tags the property with, named where the table in this Actor knows them and returned raw otherwise; the hotel page carries the full labelled list.
- **Children and rooms** are not yet inputs — prices are for the given number of adults in one room.
- **Rate limits.** Google answers these requests from datacenter IPs today; each request retries on a new IP, and a run that meets a consent page says so in the log. Residential proxies are a switch away if that changes.

### ❓ FAQ

#### Is there a Google Hotels API?

Not a public one. This Actor reads the same endpoint the Google Hotels page uses, which is why the fields match what you see on the page — including the itemised taxes and the review topics.

#### How many hotels can I get for one city?

As many as Google lists for it, up to the cap you set. The facet walk measured 197 distinct hotels for Ubud from 15 requests; a big city yields several hundred. Set `maxHotelsPerLocation` to what you need.

#### Are the prices for my dates?

Yes for `pricePerNight` and `totalPrice` — those are Google's cheapest rate across booking sites for the check-in and check-out you gave, taxes included. The per-seller `offers` from the hotel page are for Google's default stay; the row says which dates.

#### Does it include taxes?

`totalPrice` includes taxes and fees; `priceBeforeTaxes` and `taxesAndFees` are split out when Google itemises them.

#### Can I get reviews?

Yes — turn on `includeReviews` with the hotel page add-on or with `hotelUrls`. You get the reviews Google renders on the page (source, author, date, rating, text, link), typically 10–20 per hotel, plus the rating and review count per source in `reviewSources`.

#### Can I use it with the Apify API or an MCP server?

Both. Start runs and read datasets through the REST API or the Python and JavaScript clients, and call the Actor as a tool from any MCP-capable agent through the Apify MCP server.

#### Can I integrate it with other apps?

Through the Apify integrations for Google Sheets, n8n, Make and Zapier, or through webhooks on run finish.

#### Why does a default run search 30 days out?

Because a saved task or a scheduled monitor must never search a date that has already passed and come back empty. Give explicit dates and they are used; give a past date and the row says the date was adjusted.

#### Is it legal to scrape Google Hotels?

The Actor reads public pages and public data — prices, ratings, amenities — with no login and no personal data beyond reviewer display names Google already publishes. How you use the data is subject to your local law and Google's terms; consult a lawyer for your case.

#### One row per hotel?

Yes. Offers and reviews are arrays on the hotel's row; the dataset views unwind them into one line per seller or per review when you want a flat table.

### Your feedback

If a field is missing, a place returns fewer hotels than Google shows, or a price does not match the page, open an issue on the Actor with the input you used — it is answered quickly and fixed in the next build. A short review after your first run helps other people find a scraper that works.

### You might also like

| Actor | What it does |
|---|---|
| [Google Flights Scraper](https://apify.com/lergassy/google-flights-scraper) | fares, price calendar and booking options by route and dates |
| [Booking.com Hotel Search Scraper](https://apify.com/lergassy/booking-hotels-scraper) | Booking.com search with rooms, rates and reviews |
| [Agoda Reviews Scraper](https://apify.com/lergassy/agoda-reviews-scraper) | guest reviews and ratings from Agoda |
| [Trip.com Scraper](https://apify.com/lergassy/tripcom-scraper) | Trip.com hotel prices and availability |
| [Airbnb Scraper](https://apify.com/lergassy/airbnb-scraper) | vacation rental prices and availability |

### Also known as

Google Hotels API, Google Hotel Search scraper, Google Travel hotels scraper, hotel price scraper, hotel rate shopping tool, hotel price comparison API, scrape hotel prices from Google, Google hotel reviews scraper, hotel metasearch data.

# Actor input Schema

## `locations` (type: `array`):

One place per line, the way you would type it into Google Hotels: a city (<code>Lisbon</code>), a neighbourhood (<code>Shibuya, Tokyo</code>), a region or a landmark (<code>hotels near Eiffel Tower</code>). Each place is searched separately.

## `checkIn` (type: `string`):

Format <code>YYYY-MM-DD</code>. Leave empty and the Actor searches a stay 30 days from today, so a saved task never runs on a date that has passed.

## `checkOut` (type: `string`):

Format <code>YYYY-MM-DD</code>. Leave empty for a two-night stay. Prices are the total for the whole stay and the average per night.

## `adults` (type: `integer`):

Number of adult guests in one room, 1–8. Google prices the room for this many people.

## `maxHotelsPerLocation` (type: `integer`):

Google shows 20 hotels per page and stops there. This Actor keeps going through sort orders, star classes and price bands and de-duplicates by hotel, so it can collect well over a hundred hotels for one city. Set how many you want per place.

## `currency` (type: `string`):

Three-letter code for every price in the output: <code>USD</code>, <code>EUR</code>, <code>GBP</code>, <code>IDR</code> …

## `sortBy` (type: `string`):

Which of Google's orders to read first. The deep search visits the other orders anyway; this one decides the first page and the <code>searchRank</code> numbering.

## `hotelClass` (type: `array`):

Keep only these hotel classes, e.g. <code>4</code> and <code>5</code>. Unrated properties are dropped when this is set.

## `minRating` (type: `string`):

Drop hotels rated below this, on Google's 5-point scale. Hotels without a rating are dropped too.

## `maxPricePerNight` (type: `integer`):

In the output currency. Hotels whose average nightly price is above this are not returned.

## `poolOnly` (type: `boolean`):

Only hotels with a pool.

## `includeOffers` (type: `boolean`):

For each hotel, also open its Google Hotels page and return every booking site with its price and deep link (Booking.com, Expedia, Agoda, the hotel's own site …), the full amenity list, the full address and phone, and review scores per source. One extra request per hotel, charged as a hotel page read. The offers on that page are for the stay Google shows by default (about two weeks out) — the searched dates' price is in <code>pricePerNight</code>.

## `maxOfferLookups` (type: `integer`):

Cap on the add-on above, so a wide search does not open every page.

## `includeReviews` (type: `boolean`):

Include the reviews Google shows on the hotel page (text, rating, date, source such as Tripadvisor or Trip.com). Needs the hotel page, so it works together with the add-on above or with hotel URLs.

## `maxReviews` (type: `integer`):

Up to what Google renders on the page — typically 10 to 20.

## `hotelUrls` (type: `array`):

Google Hotels page URLs (<code>https://www.google.com/travel/hotels/entity/…</code>) or entity ids from an earlier run. Each becomes one row with offers, reviews and the full amenity list — no search needed.

## `language` (type: `string`):

Two-letter code for names, descriptions and amenity labels, e.g. <code>en</code>, <code>de</code>, <code>es</code>.

## `market` (type: `string`):

Two-letter country code Google prices for, e.g. <code>US</code>, <code>GB</code>, <code>DE</code>. Sellers and rates differ per market.

## `proxyConfiguration` (type: `object`):

Google answers this Actor's requests from ordinary datacenter IPs; the default Apify proxy is enough. Switch to residential only if a run reports consent pages or empty answers.

## `maxRequestRetries` (type: `integer`):

Each retry uses a new IP.

## Actor input object example

```json
{
  "locations": [
    "Ubud, Bali"
  ],
  "adults": 2,
  "maxHotelsPerLocation": 40,
  "currency": "USD",
  "sortBy": "relevance",
  "poolOnly": false,
  "includeOffers": false,
  "maxOfferLookups": 20,
  "includeReviews": false,
  "maxReviews": 10,
  "language": "en",
  "market": "us",
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxRequestRetries": 3
}
```

# Actor output Schema

## `hotels` (type: `string`):

One row per hotel: name, star class, guest rating and review count, nightly and total price with taxes for the searched stay, amenities, coordinates, address, photos, check-in times, Google Hotels page and booking link — plus per-site offers, review sources and guest reviews when the hotel page is read.

## `summary` (type: `string`):

Counts of locations, hotels, hotel pages read, requests and errors, with the searched dates.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "locations": [
        "Ubud, Bali"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lergassy/google-hotels-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "locations": ["Ubud, Bali"] }

# Run the Actor and wait for it to finish
run = client.actor("lergassy/google-hotels-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "locations": [
    "Ubud, Bali"
  ]
}' |
apify call lergassy/google-hotels-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lergassy/google-hotels-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/DAh80WIxsusrgDrgD/builds/fn4ARqHR5RrodebOh/openapi.json
