# Google Hotels Scraper - Hotel Prices & Ratings (`dataio/google-hotels-scraper`) Actor

Scrape Google Hotels for any city and dates: nightly and total hotel prices, guest rating, reviews, stars, GPS and website. Extract up to 1,000 hotels per city, build a price calendar over 60 check-in dates, filter out vacation rentals. No browser, fast, pay per hotel.

- **URL**: https://apify.com/dataio/google-hotels-scraper.md
- **Developed by:** [Tom Awake](https://apify.com/dataio) (community)
- **Categories:** Travel, E-commerce, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 hotel with a prices

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?

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 every hotel that Google Hotels shows for a city
and your dates: the **nightly and total price**, guest rating, review count,
hotel class, GPS coordinates, website, check-in times and photos. Think of it
as a **Google Hotels API**: give it cities and dates, get one clean row per
hotel.

- **Your dates, verified.** Each row says whether Google priced it for the
  dates you asked (`datesApplied`). Measured: 180 of 180 rows.
- **Up to 1,000 hotels per city.** The actor follows Google's pages, 20 hotels
  each. Measured: 134 unique hotels over 7 pages in Lyon, with no duplicate.
- **Hotel price calendar.** Give up to 60 check-in dates and a stay length, and
  get every hotel's rate for each date in a single run. Revenue managers use it
  to compare rates week over week.
- **Fast, no browser.** The actor reads Google's own data feed. It fetched 50
  hotels for two Paris stays in 27 seconds.
- **Hotels only if you want.** Google mixes vacation rentals into hotel
  results. Every row carries `isVacationRental`, and one switch removes them.

### What data can you extract from Google Hotels?

| Data | Fields |
|---|---|
| Price | `pricePerNight`, `pricePerNightExact`, `totalPrice`, display strings, `nativeCurrency` |
| Price in your currency | `pricePerNightConverted`, `totalPriceConverted`, `currency` |
| Reputation | `overallRating`, `reviewCount`, `hotelClass`, `hotelType` |
| Location | `latitude`, `longitude`, `countryCode`, `nearbyPlaces` |
| Contact and details | `website`, `checkInTime`, `checkOutTime`, `imageUrls` |
| Identifiers | `googleHotelId`, `propertyToken`, `googleHotelsUrl`, `position` (rank on Google) |
| Quality flags | `datesApplied`, `available`, `isVacationRental` |

### How to scrape Google Hotels

1. Enter one or more **locations**: `Lyon`, `Shinjuku, Tokyo`, `near the Louvre, Paris`.
2. Pick a **check-in and check-out date**, or several check-in dates for a price calendar.
3. Optionally set filters: minimum rating, minimum stars, maximum price per night, hotels only.
4. Click **Start**, then download the results as JSON, CSV or Excel, or read them through the API.

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

You pay per hotel returned **with a price**. Sold-out hotels, which have no
price, are delivered for free. At the listed price:

| Job | Hotels | Cost |
|---|---|---|
| One city, one stay | 100 | about $0.30 |
| One city, 4-week price calendar | 4 × 100 | about $1.20 |
| 10 cities, one stay | 1,000 | about $3 |

Subscription plans pay less per hotel. If a run reaches the spending limit you
set, the output stops at that limit and never goes past it.

### Input example

```json
{
  "locations": ["Lyon", "Barcelona"],
  "checkInDates": ["2026-10-15", "2026-10-22", "2026-10-29", "2026-11-05"],
  "nights": 2,
  "maxResultsPerLocation": 100,
  "currency": "EUR",
  "includeVacationRentals": false
}
```

### Output example

```json
{
  "position": 4,
  "locationQuery": "Lyon",
  "hotelName": "TRIBE Lyon Croix Rousse",
  "hotelClass": 4,
  "overallRating": 4.7,
  "reviewCount": 848,
  "checkInDate": "2026-10-15",
  "checkOutDate": "2026-10-17",
  "nights": 2,
  "datesApplied": true,
  "pricePerNight": 108,
  "pricePerNightExact": 107.57,
  "totalPrice": 215,
  "nativeCurrency": "EUR",
  "pricePerNightConverted": 123.47,
  "currency": "USD",
  "latitude": 45.7829,
  "longitude": 4.8343,
  "website": "https://all.accor.com/...",
  "isVacationRental": false,
  "googleHotelsUrl": "https://www.google.com/travel/hotels/entity/..."
}
```

### Use the Google Hotels API in Python

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("DataIO/google-hotels-scraper").call(run_input={
    "locations": ["Lyon"], "checkInDate": "2026-10-15", "checkOutDate": "2026-10-17",
})
for hotel in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(hotel["hotelName"], hotel["pricePerNightConverted"], hotel["overallRating"])
```

The same works from JavaScript, Make, Zapier, n8n, or AI agents through the
Apify MCP server.

### Other actors you might like

- [Google Trends Scraper & API](https://apify.com/DataIO/google-trends-scraper): search interest for up to 100 keywords on one scale.
- [Kalshi Weather Prediction Markets](https://apify.com/DataIO/kalshi-weather-markets): temperature market odds joined with live weather station data.
- [Steam Regional Pricing](https://apify.com/DataIO/steam-regional-pricing-intelligence): the same product priced in 50 markets at once.

### FAQ

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

The actor reads prices and hotel details that Google shows publicly, without
logging in. It collects no personal data about individuals. How you use the
data (terms of service, local law) is your responsibility. When in doubt, ask
a lawyer.

#### Why is the price in a different currency?

Google ignores every currency setting and shows the currency of the visitor's
country. Every row keeps the original price and currency, and adds a
conversion at today's rate (open.er-api.com). The conversion is an estimate,
not what the booking site will charge.

#### Can I choose the number of guests?

No. Google ignores a guest count written into the search, so we don't offer a
setting we can't honour. Prices are for the occupancy Google shows by default.

#### Can I track hotel prices every day?

Yes. Schedule the actor and leave the dates empty: the default stay is always
14 days ahead, so a daily schedule gives you a rolling two-week-out rate for
every hotel.

#### What if Google refuses some requests?

The actor switches to a new proxy session and retries. If a location still
fails, it delivers what it has collected and names the incomplete locations in
the status message. Residential proxies work best.

### Source

Public Google Hotels search results. This actor is not affiliated with or
endorsed by Google. Exchange rates: open.er-api.com.

# Actor input Schema

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

Cities, districts or landmarks, one per line: "Lyon", "Shinjuku, Tokyo", "near the Louvre, Paris". Each is searched as "hotels in <location>"; a line that already mentions hotels ("boutique hotels near the Louvre") is used as written. Up to 50.

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

YYYY-MM-DD. Defaults to 14 days from today.

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

YYYY-MM-DD. Defaults to one night after check-in.

## `checkInDates` (type: `array`):

Optional. One stay per date, all with the same length (below), in a single run: the way a revenue manager compares rates week over week. Overrides the two dates above. Up to 60.

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

Length of each stay when a price calendar is used.

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

Three-letter code. Google picks the displayed currency from the visitor's IP address and ignores any currency setting, so every row carries both the original price and a conversion at today's rate.

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

1 to 5. Applied after collection.

## `minHotelClass` (type: `integer`):

1 to 5. Hotels without an official class are excluded when this is set.

## `includeVacationRentals` (type: `boolean`):

Google Hotels mixes hotels with apartments and studios. Measured in Lyon: 40 of 180 rows were vacation rentals. Turn off to keep hotels only; every row also carries isVacationRental.

## `maxPricePerNight` (type: `number`):

In the currency chosen above.

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

Google returns 20 hotels per page; the actor follows the pages up to this number. Measured: 134 unique hotels over 7 pages in Lyon, with no duplicate.

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

Two-letter code passed to Google as the searcher's country.

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

Google blocks repeated requests from the same address. Residential proxies are the most reliable.

## Actor input object example

```json
{
  "locations": [
    "Lyon"
  ],
  "nights": 1,
  "currency": "USD",
  "includeVacationRentals": true,
  "maxResultsPerLocation": 20,
  "countryCode": "us",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Every row produced by the run, in JSON.

# 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": [
        "Lyon"
    ],
    "currency": "USD",
    "maxResultsPerLocation": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("dataio/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": ["Lyon"],
    "currency": "USD",
    "maxResultsPerLocation": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

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

```

## MCP server setup

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