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

Scrape Google Hotels for any city and dates: nightly and total prices, deals, ratings, reviews, amenities, location and photos. Optional prices from every booking site.

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

## Pricing

from $1.00 / 1,000 hotel results

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

## Google Hotels Scraper

Get hotel prices for your exact dates from [Google Hotels](https://www.google.com/travel/hotels) for any city, neighborhood or region. Each hotel comes with its price per night and for the whole stay, any current deal, guest rating and review breakdown, star class, amenities, location details and photos. Turn on one option to also get the price from every booking site that lists the hotel, such as Booking.com, Expedia, Agoda and the hotel's own website.

No browser, no login and no Google API key needed. Results download as JSON, CSV or Excel, or arrive in your app through the Apify API.

### What data you get

- **Prices for your dates**: per night and in total, before and after taxes, in the currency you choose
- **Deals**: Google's deal labels, such as "21% less than usual"
- **Reviews**: guest rating, review count, how many reviews gave each star rating, and the topics guests mention most (service, location, breakfast…) with positive and negative counts
- **Hotel details**: star class, amenities (Free Wi-Fi, pool, spa, parking…), eco-certification, property type, check-in and check-out times, description, website
- **Location**: coordinates, Google Maps link, location score, and nearby airports, transit stops, sights and restaurants with travel times
- **Photos**: up to 20 high-resolution photo URLs per hotel
- **Booking-site prices** (optional): every site's price per night and total, a link to that site's offer, plus the hotel's address and phone number

### What people use it for

- **Hotel price monitoring**: schedule a daily run with a relative date such as "30 days" and track how rates move
- **Competitive rate checks** for hotels and revenue managers: see how your rates compare with nearby properties across booking sites
- **Travel apps and AI agents**: live hotel availability and prices without an official API
- **Market research**: average prices by city, season, star class or neighborhood
- **Hotel lead lists**: names, websites, phone numbers and locations

### How to use it

1. Add one or more **search queries**, the same way you would type them into Google Hotels: `hotels in Lisbon`, `Shinjuku`, `resorts in Bali`.
2. Pick the **check-in date** and **nights**. A relative date like `14 days` always means 14 days after the day the run starts, which keeps scheduled runs pointed at the future.
3. Set **guests**, **currency** and the **number of hotels per query**.
4. Optionally add **filters** (price range, star class, minimum rating, free cancellation) and choose a **sort order**.
5. Turn on **Add prices from every booking site** if you need the per-site comparison.
6. Run it and download the results.

#### Input example

```json
{
    "queries": ["hotels in Tokyo", "hotels in Osaka"],
    "checkInDate": "2026-12-10",
    "nights": 3,
    "adults": 2,
    "childrenAges": ["8"],
    "currency": "USD",
    "maxResults": 100,
    "sortBy": "lowestPrice",
    "hotelClass": ["4", "5"],
    "minRating": "4.0",
    "includeProviderPrices": false
}
```

#### Output example

One record per hotel (shortened):

```json
{
    "name": "HOTEL THE CELESTINE TOKYO SHIBA",
    "query": "hotels in Tokyo",
    "position": 21,
    "hotelClass": 5,
    "rating": 4.3,
    "reviewsCount": 1941,
    "locationRating": 3.4,
    "currency": "USD",
    "pricePerNight": 224.35,
    "pricePerNightWithTaxes": 247,
    "totalPrice": 673,
    "totalPriceWithTaxes": 740,
    "deal": "21% less than usual",
    "dealType": "DEAL",
    "checkInDate": "2026-10-20",
    "checkOutDate": "2026-10-23",
    "nights": 3,
    "checkInTime": "3:00 PM",
    "checkOutTime": "12:00 PM",
    "amenities": ["Free Wi-Fi", "Parking ($)", "Fitness center", "Bar", "Restaurant", "Accessible", "Kid-friendly"],
    "ecoCertified": true,
    "website": "https://www.celestinehotels.jp/tokyo-shiba/",
    "googleMapsUrl": "https://www.google.com/maps?cid=2414549791662245438",
    "latitude": 35.650874,
    "longitude": 139.748867,
    "ratingHistogram": { "5": 1029, "4": 623, "3": 221, "2": 36, "1": 32 },
    "reviewMentions": [{ "aspect": "Service", "mentions": 196, "positive": 169, "negative": 19 }],
    "nearbyPlaces": [
        {
            "name": "Haneda Airport",
            "category": "airport",
            "travelTimes": [
                { "mode": "taxi", "duration": "20 min" },
                { "mode": "publicTransport", "duration": "2 hr 31 min" }
            ]
        }
    ],
    "images": ["https://lh4.googleusercontent.com/proxy/...=s1024"],
    "googleHotelsUrl": "https://www.google.com/travel/hotels/entity/ChcIvoyWhOKHjcEhGgsvZy8xMjJydjdzZxAB?...",
    "address": "3 Chome-23-1 Shiba, Minato City, Tokyo 105-0014, Japan",
    "phone": "+81 3-5441-4111",
    "providerPrices": [
        { "provider": "HOTEL THE CELESTINE TOKYO SHIBA", "isOfficialSite": true, "pricePerNight": 224.35, "totalPriceWithTaxes": 740.34, "url": "https://..." },
        { "provider": "Agoda", "isOfficialSite": false, "pricePerNight": 264.06, "totalPriceWithTaxes": 871.39, "url": "https://www.agoda.com/..." }
    ]
}
```

`address`, `phone` and `providerPrices` are only filled when **Add prices from every booking site** is on.

### Pricing

You pay per hotel returned, and Apify platform usage is included:

- **Hotel result**: each hotel from the search results
- **Hotel with booking-site prices**: each hotel when booking-site prices are turned on (this opens one more page per hotel)

Current prices are on the **Pricing** tab. You can set a maximum cost per run in the run options, and the scraper stops cleanly when it reaches it. If a hotel's booking-site prices can't be loaded, that hotel is billed as a regular result.

### Tips and notes

- **About 20 hotels per page.** Google lists about 20 hotels per results page. The scraper follows the pages until it has the number you asked for, and removes any hotel that shows up on two pages.
- **Taxes depend on the country.** In countries where Google shows prices with taxes included (most of the EU, for example), `pricePerNight` already includes them and the `WithTaxes` fields stay empty.
- **Some hotels have no price.** A hotel that is sold out or not bookable for your dates is still returned, with empty price fields.
- **Search for places, not hotels.** A query for one specific hotel name usually returns no list. Search for its area instead, for example `hotels near Marina Bay`.
- **Language.** Hotel names and descriptions follow the language you choose. Amenity names are always in English, so they're consistent across countries.
- **Proxies.** Keep the default residential proxy. Google quickly blocks data-center IPs.
- **Input with a simple fix is corrected.** A check-in date in the past moves to tomorrow, and a minimum price above the maximum is swapped. The log lists every change made.

### Is it legal to scrape Google Hotels?

This scraper only collects publicly available hotel listings: business names, prices, ratings and similar facts. It doesn't collect personal data or anything behind a login. Check that your use of the data complies with the laws that apply to you and with Google's terms. If you're unsure, ask a lawyer.

### Track one hotel across many dates

To follow specific hotels' prices for every check-in date up to a year ahead, use the [Google Hotels Price Tracker](https://apify.com/stayscope/google-hotels-price-tracker). Paste the `googleHotelsUrl` values from this scraper's results into it.

### Feedback

Found a bug or need a field that's missing? Open an issue on the **Issues** tab.

# Actor input Schema

## `queries` (type: `array`):

What you would type into Google Hotels. Use a place or area, for example "hotels in Paris", "Shinjuku" or "resorts in Bali". Each query is scraped separately.

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

A fixed date (YYYY-MM-DD) or a date relative to the day of the run, such as "14 days". Relative dates keep scheduled runs pointing at the future.

## `nights` (type: `integer`):

Length of stay. Ignored when a check-out date is set.

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

Overrides the number of nights. A fixed date (YYYY-MM-DD) or relative to the day of the run.

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

Number of adult guests.

## `childrenAges` (type: `array`):

One entry per child, with their age (0-17). Leave empty for no children.

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

3-letter currency code for all prices, for example USD, EUR, GBP, JPY or MYR.

## `maxResults` (type: `integer`):

How many hotels to collect for each query. Google shows about 20 per page.

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

Order of the results.

## `minPrice` (type: `integer`):

In the selected currency.

## `maxPrice` (type: `integer`):

In the selected currency.

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

Only return hotels with these star ratings. Leave empty for all.

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

Only return hotels rated at least this high.

## `freeCancellation` (type: `boolean`):

Only return hotels that offer free cancellation for your dates.

## `includeProviderPrices` (type: `boolean`):

Opens each hotel's Google Hotels page to add the price from every booking site (Booking.com, Expedia, Agoda, the hotel's own site and more), plus the address and phone number. Slower, and billed at a higher price per hotel.

## `maxImages` (type: `integer`):

How many photo URLs to include for each hotel.

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

Google interface language code, for example en, de, fr or ja. Amenity names are always in English.

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

2-letter country code Google uses for the search, for example us, gb or my.

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

Google blocks data-center IPs quickly, so residential proxies are recommended.

## `maxConcurrency` (type: `integer`):

How many hotel pages to open at once when booking-site prices are enabled.

## Actor input object example

```json
{
  "queries": [
    "hotels in Paris"
  ],
  "checkInDate": "14 days",
  "nights": 1,
  "adults": 2,
  "currency": "USD",
  "maxResults": 20,
  "sortBy": "relevance",
  "minRating": "any",
  "freeCancellation": false,
  "includeProviderPrices": false,
  "maxImages": 3,
  "language": "en",
  "country": "us",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  },
  "maxConcurrency": 5
}
```

# Actor output Schema

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

All scraped hotels from the run's default dataset.

# 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 = {
    "queries": [
        "hotels in Paris"
    ],
    "checkInDate": "14 days",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("stayscope/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 = {
    "queries": ["hotels in Paris"],
    "checkInDate": "14 days",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("stayscope/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 '{
  "queries": [
    "hotels in Paris"
  ],
  "checkInDate": "14 days",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call stayscope/google-hotels-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,stayscope/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/acrBmvAq4GbMJYQof/builds/fWDve1O5J0e8zLKer/openapi.json
