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

Scrape Google Hotels: hotel names, nightly and total prices, ratings, reviews, stars, amenities, coordinates, images and the price of every booking site (Booking.com, Expedia, official site...) for any location and dates.

- **URL**: https://apify.com/atalaia/google-hotels.md
- **Developed by:** [Atalaia](https://apify.com/atalaia) (community)
- **Categories:** Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What does Google Hotels Scraper do?

**Google Hotels Scraper** extracts hotel listings from [Google Hotels](https://www.google.com/travel/hotels) for any city, region or area and any dates. For each hotel you get the **name, nightly price, total price for the stay, star class, guest rating, review count, amenities, coordinates, images** and, optionally, **the price offered by every booking site**: Booking.com, Expedia, Hotels.com, Trip.com, Priceline, the hotel's official website and more.

Enter a list of locations and dates, click **Start**, and download the data as JSON, CSV, Excel or HTML, or fetch it through the Apify API. Because it runs on the Apify platform, you can schedule it, call it from your own code, connect it to Make, Zapier or Google Sheets, and monitor every run.

### Why use Google Hotels Scraper?

- **Rate monitoring & revenue management.** Track how a hotel's price differs between booking sites and between dates.
- **Travel price comparison.** Feed your own comparison site or deal alerts with fresh prices from all major OTAs.
- **Market research.** Compare supply, star classes, ratings and prices across cities, neighborhoods or seasons.
- **Lead lists of properties.** Build lists of hotels with coordinates, class and rating for a destination (business listing data only, no personal data).

The Actor reads the structured data Google embeds in the page rather than the visual layout, so it's fast and cheap (no browser) and less likely to break when Google restyles the page.

### How to scrape Google Hotels

1. Open the Actor and go to the **Input** tab.
2. Add one or more **locations**, for example `Lisbon`, `New York` or `Rio de Janeiro`.
3. Pick the **check-in and check-out dates**, guests, **currency**, **language** and **country**.
4. Choose how many hotels you want per location and whether to include **booking-site prices**.
5. Click **Start**. When the run finishes, open the **Output** tab or export the dataset.

### Input

All fields except `locations` are optional.

| Field | Type | Default | Description |
|---|---|---|---|
| `locations` | string\[] | (required) | Places to search, as you'd type them after "hotels in". One search per location. |
| `checkInDate` | YYYY-MM-DD | today + 14 | Check-in date. |
| `checkOutDate` | YYYY-MM-DD | today + 15 | Check-out date (1 to 30 nights). |
| `adults` | integer | 2 | Number of adults. |
| `children` | integer | 0 | Number of children (sent to Google as 10 years old each). |
| `currency` | string | USD | ISO currency code for all prices. |
| `language` | string | en | Google interface language (`hl`), e.g. `en`, `pt-BR`, `es`, `ja`. |
| `country` | string | us | Google country (`gl`), e.g. `us`, `br`, `gb`, `jp`. |
| `maxResultsPerLocation` | integer | 50 | Maximum hotels per location (up to 500). The Actor paginates automatically. |
| `includeVendorPrices` | boolean | true | Also collect the price of each booking site and the street address (one extra request per hotel). |
| `proxyConfiguration` | object | Apify Proxy | Network settings. The default works; you normally don't need to change it. |

Example input:

```json
{
    "locations": ["Lisbon", "New York"],
    "checkInDate": "2026-10-17",
    "checkOutDate": "2026-10-19",
    "adults": 2,
    "currency": "EUR",
    "language": "en",
    "country": "us",
    "maxResultsPerLocation": 50,
    "includeVendorPrices": true
}
```

### Output

One item per hotel. Example (shortened):

```json
{
    "query": "hotels in Tokyo",
    "location": "Tokyo",
    "checkIn": "2026-10-17",
    "checkOut": "2026-10-19",
    "rank": 2,
    "name": "ONE@Tokyo by insomnia",
    "googleHotelId": "8513623909204002594",
    "propertyToken": "ChoI84KEy5HjiaeGARoNL2cvMTFkeGp4MnEyXxAB",
    "url": "https://www.google.com/travel/hotels/entity/ChoI84KEy5HjiaeGARoNL2cvMTFkeGp4MnEyXxAB?q=hotels+in+Tokyo&...",
    "address": "1 Chome-19-3 Oshiage, Sumida City, Tokyo 131-0045, Japan",
    "latitude": 35.7117889,
    "longitude": 139.8159778,
    "stars": 3,
    "hotelClass": "3-star hotel",
    "rating": 4.3,
    "reviewCount": 1004,
    "pricePerNight": 148.03,
    "totalPrice": 296.06,
    "currency": "EUR",
    "amenities": ["Free Wi-Fi", "Accessible", "Kid-friendly"],
    "images": ["https://lh3.googleusercontent.com/..."],
    "description": "Industrial-chic quarters & a cafe in a choice hotel offering a rooftop lounge with skyline views.",
    "vendorPrices": [
        { "vendor": "ONE@Tokyo by insomnia", "price": 181.94, "priceText": "€182", "totalPrice": 363.88, "url": "https://...", "isOfficialSite": true },
        { "vendor": "Priceline", "price": 148.03, "priceText": "€148", "totalPrice": 296.06, "url": "https://www.priceline.com/...", "isOfficialSite": false }
    ],
    "scrapedAt": "2026-09-29T04:05:00.000Z"
}
```

If a location can't be scraped after several retries, the dataset gets one item like `{ "query": "hotels in X", "location": "X", "error": "..." }`. These error items are **not charged**. You can download the dataset in various formats such as JSON, HTML, CSV or Excel.

#### Data fields

| Field | Description |
|---|---|
| `name`, `googleHotelId`, `propertyToken`, `url` | Hotel identity and its Google Hotels page for your dates |
| `pricePerNight`, `totalPrice`, `currency` | Lowest nightly price, and the total for the stay including taxes and fees |
| `stars`, `hotelClass`, `rating`, `reviewCount` | Hotel class and Google guest rating |
| `latitude`, `longitude`, `address` | Location (`address` only with `includeVendorPrices`) |
| `amenities`, `images`, `description` | Amenities, up to 5 image URLs, short description |
| `vendorPrices[]` | `vendor`, nightly `price`, `totalPrice`, direct offer `url`, `isOfficialSite` |
| `rank`, `query`, `location`, `checkIn`, `checkOut`, `adults`, `children`, `scrapedAt` | Search context |

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

This Actor uses **pay-per-event** pricing. You only pay for results you get:

| Event | Price | When |
|---|---|---|
| `hotel` | $0.003 | per hotel returned ($3 per 1,000 hotels) |
| `vendor-prices` | $0.002 | per hotel whose booking-site prices were collected (only with `includeVendorPrices`) |

Example: 1,000 hotels with booking-site prices cost **$5.00**; without booking-site prices, **$3.00**. Failed locations are never charged. Platform usage is included in the price.

### Tips

- Turn **off** `includeVendorPrices` if you only need the list of hotels and the lowest price. It's cheaper and about 3x faster.
- Use `maxResultsPerLocation` to cap costs. Google returns about 18 new hotels per page.
- Prices depend on the dates, the number of guests and the `country`. Keep them fixed when you compare prices over time.
- For many dates, run the Actor once per date range (or use Apify Tasks and Schedules).

### Limitations

- Results and their order are what Google shows to an anonymous visitor. They can include vacation-rental style listings next to hotels, and the ranking can differ slightly from your personalized browser view.
- Amenity names are always in English. Hotel cards expose the most common amenities (Wi-Fi, pool, parking, breakfast, spa, ...), not the full amenity list from the hotel's "About" page.
- Some listings have no star class, rating or address on Google; those fields are `null`.
- `children` are sent with age 10.
- Booking-site links point directly to the offer at the moment of scraping. Offers expire and prices change constantly.

### FAQ

**Is it legal to scrape Google Hotels?** The Actor only collects publicly visible business listing data (hotels, prices, ratings). It doesn't collect personal data and doesn't log in. You're responsible for how you use the data: check the terms of the sites involved and the laws that apply to you.

**Something is broken or missing?** Please open an issue in the **Issues** tab with the input you used. We fix problems quickly.

# Actor input Schema

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

Cities, regions or areas to search, exactly as you would type them after "hotels in" on Google Hotels. One search per location.

## `checkInDate` (type: `string`):

Check-in date (YYYY-MM-DD). Defaults to today + 14 days.

## `checkOutDate` (type: `string`):

Check-out date (YYYY-MM-DD). Defaults to check-in + 1 day (today + 15 days). Maximum stay: 30 nights.

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

Number of adult guests.

## `children` (type: `integer`):

Number of children (each child is sent to Google as 10 years old).

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

3-letter ISO currency code for prices, e.g. USD, EUR, BRL, JPY.

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

Google interface language code (hl), e.g. en, pt-BR, es, de, ja. Affects hotel names/descriptions where Google localizes them.

## `country` (type: `string`):

Google country code (gl), e.g. us, br, gb, de, jp.

## `maxResultsPerLocation` (type: `integer`):

Stop after this many hotels per location. The Actor paginates Google results (about 18 new hotels per page) until this number is reached or results run out.

## `includeVendorPrices` (type: `boolean`):

Open each hotel's price page to collect the price offered by every booking site (Booking.com, Expedia, the hotel's own website, ...) plus the street address. Needs one extra request per hotel and is charged as a separate `vendor-prices` event.

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

Apify Proxy is used by default. You normally don't need to change this.

## Actor input object example

```json
{
  "locations": [
    "Lisbon"
  ],
  "adults": 2,
  "children": 0,
  "currency": "USD",
  "language": "en",
  "country": "us",
  "maxResultsPerLocation": 50,
  "includeVendorPrices": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset with one item per hotel (plus error items for failed locations)

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

Per-location counts and errors

# 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": [
        "Lisbon"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("atalaia/google-hotels").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": ["Lisbon"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("atalaia/google-hotels").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": [
    "Lisbon"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call atalaia/google-hotels --silent --output-dataset

```

## MCP server setup

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

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/CgYB6otcc4EuXbHU1/builds/zxvdCKThQnjhWvIuK/openapi.json
