# Google Hotels Scraper - Hotel Prices, Ratings & Booking Offers (`datagleaner/google-hotels-scraper`) Actor

Google Hotels scraper for hotel prices on your exact dates: search any city or look up hotels and get the lowest rate, every booking site's price (Booking.com, Agoda, Trip.com), ratings, amenities and coordinates. Hotel price tracking and comparison over plain HTTP, no browser, no login.

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

## Pricing

$3.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 API - Hotel Price Comparison, Ratings & Booking Offers

Scrape Google Hotels prices for your exact dates: search any city or hotel and get the lowest rate plus every booking site's price and link (Booking.com, Agoda, Trip.com, Hostelworld and more), with ratings, star class, amenities, photos and coordinates, as one clean JSON record per hotel.

It works as a Google Hotels API for hotel price tracking and Booking.com price comparison: filter by rating, stars and price, and skipped hotels are free. It calls Google Travel over plain HTTP: no browser, no login, no Google account. A 100-hotel search takes about 7 requests; full details add one request per hotel.

### What does Google Hotels Scraper do?

It reads the same results a visitor sees on Google Hotels for a city, neighbourhood or hotel name, and returns them as JSON, CSV or Excel through the Apify dataset and API. Typical uses:

- **Hotel price tracking:** run daily for the same dates and track a city or a hotel set over time.
- **Hotel price comparison:** see which provider is cheapest for each hotel, and the spread between providers.
- **Market research:** map hotel supply, ratings and price levels in any neighbourhood.
- **Travel apps and AI agents:** feed date-specific hotel prices into an itinerary tool or an LLM agent.

### Input

| Field | Meaning |
|---|---|
| `locations` | Free text: `Tokyo`, `Paris 8e`, `Waikiki, Honolulu`, `hostels in Berlin`. Plain place names are searched as "hotels in ...". |
| `hotelUrls` | Detail mode. Google Hotels hotel URLs or the bare `entityId` from earlier results. |
| `checkIn`, `checkOut` | `YYYY-MM-DD`. Default: 30 days from today, 2 nights. Prices are for these dates. |
| `adults` | 1 to 8. Default 2. |
| `currency` | ISO code, default `USD`. |
| `maxHotelsPerLocation` | Default 20, max 1000. Pages are followed until reached or Google has no more. |
| `minRating` | 1 to 5, e.g. `4.2`. Hotels with no rating are skipped. |
| `hotelClass` | Star classes to keep, e.g. `["4", "5"]`. Unclassed guest houses, hostels and apartments are skipped. |
| `minPrice`, `maxPrice` | Lowest nightly price for your dates, in your currency. Hotels with no price for your dates are skipped when either is set. |
| `sortBy` | `lowestPrice`, `highestRating` or `mostReviewed`. Off by default (Google's order, kept in `position`). When set, the Actor first collects about three times `maxHotelsPerLocation` matching hotels per location (at least 60, at most 200, and never fewer than you asked for) and returns the best `maxHotelsPerLocation` by that order, so you get the cheapest or best-rated of the area, not of the first page. Hotels without the value come last. |
| `includeDetails` | Default on. One extra request per hotel adds address, check-in times, website and the provider offers. Off gives a fast list with only the lowest price. |
| `language`, `countryCode` | Interface language (`en`) and market (`us`). |
| `requestDelaySecs` | Pacing between requests, default 1.5. |
| `proxyConfiguration` | Optional, off by default. |

Filters and `sortBy` apply to `locations` searches only, not to `hotelUrls` lookups. Hotels skipped by a filter are not charged. If you already call another Google Hotels Actor, these input names are also accepted: `checkInDate`, `checkOutDate`, `maxResults` (same as `maxHotelsPerLocation`, and it wins if both are set) and `searchQuery` (a location string). With no input at all, the Actor runs a built-in example of 5 hotels in Paris.

```json
{
  "locations": ["Tokyo", "Paris 8e"],
  "checkIn": "2026-11-10",
  "checkOut": "2026-11-12",
  "adults": 2,
  "currency": "USD",
  "maxHotelsPerLocation": 50,
  "minRating": 4.2,
  "hotelClass": ["4", "5"],
  "sortBy": "lowestPrice"
}
```

### Output

```json
{
  "name": "Le Tsuba Hotel",
  "position": 1,
  "entityId": "ChkI8bPIkrOozLonGg0vZy8xMWNseWdzeDVmEAE",
  "url": "https://www.google.com/travel/hotels/entity/ChkI8bPIkrOozLonGg0vZy8xMWNseWdzeDVmEAE?hl=en&gl=us&ts=...",
  "address": "45 Rue des Acacias, 75017 Paris, France",
  "latitude": 48.877756,
  "longitude": 2.2930822,
  "countryCode": "FR",
  "starClass": 4,
  "propertyType": "4-star tourist hotel",
  "rating": 4.6,
  "reviewCount": 1590,
  "amenities": ["Free Wi-Fi", "Air conditioning", "Pet-friendly", "Fitness center", "Parking"],
  "thumbnail": "https://lh3.googleusercontent.com/...",
  "website": "http://www.tsubahotel.com/",
  "phone": "+33 1 ...",
  "checkInTime": "3:00 PM",
  "checkOutTime": "12:00 PM",
  "lowestPrice": 185.28,
  "cheapestProvider": "Bluepillow.tw",
  "offersCount": 2,
  "currency": "USD",
  "lowestPriceDisplay": "$185",
  "totalPriceDisplay": "$371",
  "pricesForDates": true,
  "offers": [
    {"provider": "Bluepillow.tw", "pricePerNight": 185.28, "priceDisplay": "$185", "totalPrice": 370.56, "totalPriceDisplay": "$371", "isSponsored": false, "link": "https://www.google.com/travel/lodging/clk?..."},
    {"provider": "Amimir.com", "pricePerNight": 193.7, "priceDisplay": "$194", "totalPrice": 387.4, "totalPriceDisplay": "$387", "isSponsored": false, "link": "https://www.google.com/travel/lodging/clk?..."}
  ],
  "searchLocation": "Paris 8e",
  "checkIn": "2026-11-10",
  "checkOut": "2026-11-12",
  "nights": 2,
  "adults": 2,
  "source": "search",
  "scrapedAt": "2026-10-07T15:59:05+00:00"
}
```

`position` is the hotel's 1-based rank in Google's results for that location, useful for rank tracking (null for `hotelUrls` lookups). `cheapestProvider` and `offersCount` summarize `offers`; each offer has `isSponsored`, true when the offer's link is a Google ad click-through (shown as Sponsored on Google). With full details on, records also carry `tagline`, `description` (Google's longer text; some hotels have none) and `ratingsBreakdown` (per-star `percent` and `count`, 5 stars first). Prices are as Google Hotels shows them for your market (`countryCode`); whether taxes and fees are included follows Google's display for that market.

The dataset has two views: **Hotels** (one row per hotel with the lowest price and cheapest site) and **Offers** (one row per booking-site offer, for every hotel).

Records also carry `imageUrls` (up to 5 photos) and `googlePlaceId` when Google provides them. `lowestPrice` and each `pricePerNight` are per night; `totalPrice` is for the whole stay. `pricesForDates` confirms Google priced the exact dates you asked for. A hotel with no availability on those dates is still returned, with `lowestPrice: null` and empty `offers`.

### Pricing

Pay per result: **$3.00 per 1,000 hotels** ($0.003 per hotel). You pay only for hotels pushed to the dataset (hotels skipped by your filters cost nothing, so filtered runs are cheaper), and the run stops at your maximum charge. A 10-hotel test run costs $0.03.

Worked example: 5 cities at 100 hotels each is 500 hotels, which costs $1.50. Re-running the same set every day for 30 days costs $45.

### Use it from the API

Run it synchronously and get the hotels back as JSON. Replace `<YOUR_APIFY_TOKEN>` with your token.

```bash
curl -X POST "https://api.apify.com/v2/acts/datagleaner~google-hotels-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"locations": ["Tokyo"], "checkIn": "2026-11-10", "checkOut": "2026-11-12", "maxHotelsPerLocation": 20}'
```

It also works from n8n, Make or Zapier through the Apify integrations, since the output is a flat JSON record per hotel.

### Use with Python

`pip install apify-client`, set the `APIFY_TOKEN` environment variable, and run. This input returns at most 10 hotels, about $0.03.

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("datagleaner/google-hotels-scraper").call(run_input={
    "locations": ["Tokyo"],
    "checkIn": "2026-11-10",
    "checkOut": "2026-11-12",
    "currency": "USD",
    "maxHotelsPerLocation": 10,
})
for hotel in client.dataset(run.default_dataset_id).iterate_items():
    print(hotel["name"], hotel.get("rating"), hotel.get("lowestPrice"), hotel.get("currency"))
```

### Use with JavaScript / Node.js

`npm install apify-client`, set `APIFY_TOKEN`, and run it as an ES module (`.mjs`).

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('datagleaner/google-hotels-scraper').call({
    locations: ['Tokyo'],
    checkIn: '2026-11-10',
    checkOut: '2026-11-12',
    currency: 'USD',
    maxHotelsPerLocation: 10,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const hotel of items) console.log(hotel.name, hotel.rating, hotel.lowestPrice, hotel.currency);
```

### Use it from n8n, Make, Zapier or an AI agent

Actor ID: `datagleaner/google-hotels-scraper`

Minimal input:

```
{"locations": ["Tokyo"], "checkIn": "2026-11-10", "checkOut": "2026-11-12", "maxHotelsPerLocation": 10}
```

Each tool below runs this Actor with your own Apify API token.

- **n8n:** add the **Apify** node (`@apify/n8n-nodes-apify`). On n8n Cloud you install it from the community node registry. Choose **Run an Actor and get dataset**, set Actor to `datagleaner/google-hotels-scraper` and paste the input above.
- **Make:** use the Apify app's **Run an Actor** module, then **Get Dataset Items** to read the results. **Watch Actor Runs** can trigger a scenario when a run finishes.
- **Zapier:** use the Apify action **Run Actor**, then the search **Fetch dataset items**. The trigger **Finished Actor run** starts a Zap when a run ends.
- **AI agents (MCP):** connect to `https://mcp.apify.com?tools=datagleaner/google-hotels-scraper`. In Claude Code:

  ```
  claude mcp add --transport http apify "https://mcp.apify.com?tools=datagleaner/google-hotels-scraper"
  ```

  Then run `/mcp` to sign in to Apify in your browser. Then ask in plain language, for example: "Find 10 hotels in Shinjuku, Tokyo for 2 adults from November 10 to 12, prices in USD, and tell me which booking site is cheapest for each." An agent without the Actor preloaded can find it with Apify's `search-actors` tool by searching "google hotels".
- **LangChain (Python):**

```python
## pip install langchain-apify, then set APIFY_TOKEN in your environment
import json
from langchain_apify import ApifyActorsTool
tool = ApifyActorsTool("datagleaner/google-hotels-scraper")
result = tool.invoke({"run_input": json.loads('{"locations": ["Tokyo"], "checkIn": "2026-11-10", "checkOut": "2026-11-12", "maxHotelsPerLocation": 10}')})
```

### Limits

- Google lists around 500 distinct hotels per query at most. For more coverage, search sub-areas (`hotels in Shinjuku`, `hotels in Asakusa`).
- `amenities` are the highlight amenities Google shows on the result card (about 6 to 9 per hotel), not the complete list. Hotels fetched by `hotelUrls` alone carry no `amenities`.
- Providers differ by market; set `countryCode` to the market you care about.
- Dates must be today or later with check-out after check-in.
- At very high volume Google may start refusing requests. The Actor backs off, refreshes its connection and finishes what it has. Enable `proxyConfiguration` if that happens.

### FAQ

**Is there a Google Hotels API?** Google offers no public API for hotel prices. This Actor works as one: you call the Apify API with places and dates, it fetches the Google Hotels results and returns JSON.

**How do I track Google Hotels prices over time?** Schedule the Actor daily for the same locations and dates and compare `lowestPrice`, or each provider's `pricePerNight`, between runs. Each record carries `scrapedAt`.

**Which booking sites does it compare?** Every provider Google Hotels lists for that hotel in your market, such as Booking.com, Agoda, Trip.com and Hostelworld, each with its per-night price, total price and link. Provider offers need `includeDetails` on (the default).

**Are the prices real?** They are what Google Hotels shows for your dates, currency and market, and `pricesForDates` confirms Google priced the exact dates you asked for. Each offer links through Google to the provider's booking page.

**Can I get reviews or room types?** Not in this version.

### Responsible use

This Actor reads publicly visible Google Hotels pages without logging in. Use the data in line with Google's terms and the providers' terms. Hotel records are business data, not personal data; if you combine them with anything about individuals, the data-protection obligations are yours.

# Actor input Schema

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

Free-text places to search, e.g. `Tokyo`, `Paris 8e`, `Waikiki, Honolulu`. Each is searched as `hotels in <place>`; text that already names a lodging type (`hostels in Berlin`, `ski resorts near Zermatt`) is used as typed.

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

Detail mode: Google Hotels hotel page URLs (`https://www.google.com/travel/hotels/entity/Ch...`) or the bare entity ID (the `entityId` field of earlier results). Returns the full record with offers for your dates.

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

YYYY-MM-DD. Prices are specific to these dates. Defaults to 30 days from today.

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

YYYY-MM-DD, after check-in. Defaults to check-in plus 2 nights.

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

Number of adult guests.

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

ISO 4217 code for all prices, e.g. `USD`, `EUR`, `JPY`, `GBP`.

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

Google returns 20 hotels per page; pages are followed until this many distinct hotels are collected or Google has no more for the query.

## `includeDetails` (type: `boolean`):

One extra request per hotel adds the street address, check-in times, website and the per-provider price offers. Turn off for a faster, lighter list with only the lowest price.

## `minRating` (type: `number`):

Keep only hotels rated at least this (1-5), e.g. `4.2`. Filters apply to location search, are checked before the details request, and skipped hotels are not charged. Hotels with no rating are skipped when this is set.

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

Keep only these star classes, e.g. 4 and 5. Guest houses, hostels and apartments without a class are skipped when this is set.

## `minPrice` (type: `number`):

In your currency. Keep only hotels whose lowest nightly price for your dates is at least this. Hotels without a price for your dates are skipped when a price filter is set.

## `maxPrice` (type: `number`):

In your currency. Keep only hotels whose lowest nightly price for your dates is at most this, e.g. `200`.

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

Off by default (Google's own order, kept in `position`). When set, up to 60-200 matching hotels per location are looked at first and the best `maxHotelsPerLocation` by this order are returned, so you get the cheapest or best-rated of the area, not of the first page. Hotels without the value come last. Looking at more hotels costs requests, not charges.

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

Interface language code (`en`, `de`, `ja`...). Affects hotel names, addresses and price labels.

## `countryCode` (type: `string`):

Two-letter Google market (`us`, `gb`, `de`...). Providers and deals can differ by market.

## `requestDelaySecs` (type: `number`):

Polite pacing. Lower is faster and raises the chance of being blocked.

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

Optional. Off by default: Google answered datacenter IPs in testing. Enable a proxy if runs start getting blocked at high volume.

## Actor input object example

```json
{
  "locations": [
    "Tokyo"
  ],
  "adults": 2,
  "currency": "USD",
  "maxHotelsPerLocation": 20,
  "includeDetails": true,
  "language": "en",
  "countryCode": "us",
  "requestDelaySecs": 1.5
}
```

# Actor output Schema

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

No description

## `offers` (type: `string`):

No description

## `results` (type: `string`):

No description

# 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": [
        "Tokyo"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("datagleaner/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": ["Tokyo"] }

# Run the Actor and wait for it to finish
run = client.actor("datagleaner/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": [
    "Tokyo"
  ]
}' |
apify call datagleaner/google-hotels-scraper --silent --output-dataset

```

## MCP server setup

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