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

Search Google Hotels and get every hotel with prices for your dates, rating, reviews, amenities, location, photos and booking links. Optional per-site booking offers, address and phone. Fast HTTP scraper, no browser.

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

## Pricing

from $8.00 / 1,000 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

Search **Google Hotels** and get every hotel and vacation rental with **prices for your dates**, rating, reviews, amenities, location, photos and booking links. Optionally open each hotel to get the **price on every booking site** (Booking.com, Expedia, Hotels.com, the hotel's own site, ...), plus its address and phone number.

The actor talks to Google over plain HTTP — no browser — so runs are fast and cheap: 500 hotels from five searches take about half a minute.

### Features

- 🔎 **Search like on Google** — `hotels in Paris`, `beach resorts in Bali`, `vacation rentals near Lake Tahoe`. Run many searches at once.
- 💵 **Real prices for your stay** — nightly price, whole-stay total, and taxes and fees, for the dates, guests and currency you choose.
- 🏷 **Booking offers per site** — optional: every booking site's price for the hotel, with a link to each offer.
- ⭐ **Ratings in depth** — average rating, review count, reviews per star, and what guests mention (service, location, cleanliness, ...).
- 🎛 **Filters and sorting** — sort by lowest price, highest rating or most reviewed; filter by guest rating and hotel class.
- 👨‍👩‍👧 **Guests** — adults and children (with ages), so family prices are correct.
- ♾ **Automatic pagination** — pages are fetched in parallel until your limit is reached or Google runs out of results.
- 💾 **Incremental results** — hotels are saved page by page, so a long run never loses what it collected.

### Use cases

- Price monitoring and rate-parity checks across booking sites
- Competitor benchmarking for hotels and revenue managers
- Travel apps, deal finders and price-alert tools
- Market research: supply, pricing and guest sentiment by destination
- Lead lists of hotels with website, phone and address

### Quick start

1. Enter a search, e.g. `hotels in Paris`.
2. Pick check-in and check-out dates (or leave them empty for a one-night stay a week from today).
3. Run. Hotels appear in the dataset as each page completes.

### Input

| Field | Type | Description |
| --- | --- | --- |
| `searchQueries` | array | **Required.** Searches to run, as you would type them on Google Hotels. |
| `maxResults` | integer | Hotels to return per search (1–1000). Default `100`. |
| `checkInDate` / `checkOutDate` | string | `yyyy-mm-dd`, or a relative offset such as `7 days`. Default: one night, a week from today. Stays up to 30 nights. |
| `adults` | integer | Adult guests (1–10). Default `2`. |
| `childrenAges` | array | One age (0–17) per child. |
| `currency` | string | 3-letter code, e.g. `USD`, `EUR`, `GBP`. Default `USD`. |
| `sortBy` | string | `relevance`, `lowest_price`, `highest_rating` or `most_reviewed`. |
| `minRating` | string | `3.5`, `4` or `4.5` — minimum guest rating. |
| `hotelClass` | array | Star classes to keep: `2`, `3`, `4`, `5`. |
| `includeOffers` | boolean | Add per-site booking offers, address, phone and typical price range. Slower, no extra charge. Default `false`. |
| `language` | string | Language of descriptions and labels, e.g. `en`, `fr`, `pt-BR`. Default `en`. |
| `proxyConfiguration` | object | Proxy settings. The default (Apify datacenter proxy, United States) is recommended. |

#### Example

```json
{
    "searchQueries": ["hotels in Paris", "hotels in Rome"],
    "maxResults": 200,
    "checkInDate": "2026-12-18",
    "checkOutDate": "2026-12-21",
    "adults": 2,
    "currency": "EUR",
    "sortBy": "lowest_price",
    "minRating": "4",
    "includeOffers": true
}
```

### Output

One dataset item per hotel:

```json
{
    "searchQuery": "hotels in Paris",
    "position": 3,
    "name": "Hôtel Mercure Paris Porte d'Orléans",
    "type": "4-star tourist hotel",
    "hotelClass": 4,
    "description": "Modern hotel featuring streamlined quarters, plus dining & a fitness center.",
    "rating": 4,
    "reviewsCount": 1815,
    "pricePerNight": 68.18,
    "pricePerNightFormatted": "$68",
    "pricePerNightWithTaxesFormatted": "$75",
    "totalPrice": 136.36,
    "taxesAndFees": 13.64,
    "totalPriceWithTaxes": 150,
    "totalPriceWithTaxesFormatted": "$150",
    "currency": "USD",
    "deal": "39% less than usual",
    "typicalPriceRange": { "low": "$96", "high": "$129" },
    "checkIn": "2026-11-20",
    "checkOut": "2026-11-22",
    "nights": 2,
    "adults": 2,
    "children": 0,
    "address": "13 Rue François Ory, 92120 Montrouge, France",
    "countryCode": "FR",
    "latitude": 48.81763,
    "longitude": 2.3292313,
    "phone": "+33 1 58 07 11 11",
    "website": "https://all.accor.com/hotel/0374/index.fr.shtml",
    "checkInTime": "2:00 PM",
    "checkOutTime": "12:00 PM",
    "amenities": ["Paid breakfast", "Free Wi-Fi", "Paid parking", "Air conditioning", "Pet-friendly", "Fitness center"],
    "ratingsBreakdown": { "5": 839, "4": 508, "3": 230, "2": 103, "1": 135 },
    "reviewTopics": [{ "topic": "Service", "mentions": 44, "positive": 25, "negative": 16 }],
    "nearbyPlaces": [{ "name": "Catacombs of Paris", "transport": [{ "mode": "car", "duration": "10 min" }] }],
    "thumbnail": "https://lh3.googleusercontent.com/...",
    "photos": ["https://lh3.googleusercontent.com/..."],
    "offers": [
        {
            "provider": "Booking.com",
            "isOfficialSite": false,
            "pricePerNight": 95.06,
            "pricePerNightWithTaxes": 123.46,
            "totalPrice": 190.11,
            "totalPriceWithTaxes": 246.92,
            "perk": null,
            "link": "https://www.google.com/travel/lodging/clk?..."
        }
    ],
    "bookingLink": "https://www.google.com/travel/clk/hi?...",
    "googleHotelsUrl": "https://www.google.com/travel/hotels/entity/ChgIk_yPrdu8xKuuARoLL2cvMXY4Z2JiOTIQAQ",
    "googleMapsUrl": "https://www.google.com/maps?cid=12562486388467236371",
    "hotelId": "ChgIk_yPrdu8xKuuARoLL2cvMXY4Z2JiOTIQAQ",
    "placeId": "0x47e671a865cd5ea3:0xae5711e5b5a3fe13",
    "scrapedAt": "2026-10-12T11:31:17.928Z"
}
```

`offers`, `typicalPriceRange`, `address` and `phone` come from opening the hotel, so turn on **Include booking offers** to get them. `typicalPriceRange` is the hotel's usual nightly price range, which is what a `deal` such as "39% less than usual" is measured against. Vacation rentals usually publish no address or phone.

### Good to know

- **Hotels without a price.** Some hotels have no price for the chosen stay — they are sold out, have no room for that many guests, or do not share rates with Google. They are still returned, with the price fields set to `null`.
- **Prices depend on where Google thinks you are.** Google hides hotel prices for visitors from some countries, so the actor uses United States proxies unless you choose another country.
- **Amenity names are in English** regardless of the language setting.
- **Result depth.** Google lists up to roughly 500 properties per search and the run ends there. To cover a big city completely, split it into several searches — by neighbourhood (`hotels in Montmartre Paris`) or by hotel class.
- **Vague searches.** If Google cannot tell which place you mean, it may answer with hotels from somewhere else. Name the destination clearly.

### Billing

You pay per hotel saved to the dataset. Booking offers, address and phone are included in that price — turning on *Include booking offers* costs nothing extra.

The run stops on its own when it reaches the maximum charge you set, so you never pay for more than you asked for.

### Local development

```bash
npm install
npm test          # parser and input unit tests
apify run         # runs with the input in storage/key_value_stores/default/INPUT.json
```

# Actor input Schema

## `searchQueries` (type: `array`):

What to search for on Google Hotels, one search per line — exactly as you would type it, e.g. "hotels in Paris", "beach resorts in Bali" or "vacation rentals near Lake Tahoe". Each search is scraped separately.

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

How many hotels to return for each search. Google lists up to roughly 500 properties per search; use several narrower searches (by neighbourhood or hotel class) to go beyond that.

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

Arrival date (yyyy-mm-dd), or a relative offset such as "7 days". Prices are quoted for this stay. Leave empty to price a one-night stay starting a week from today.

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

Departure date (yyyy-mm-dd), or a relative offset such as "9 days". Leave empty for a one-night stay.

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

Number of adult guests.

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

One entry per child, giving the child's age (0–17). Leave empty when travelling without children.

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

3-letter currency code for prices, e.g. USD, EUR, GBP.

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

Order in which Google returns the hotels.

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

Only return hotels rated at least this high.

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

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

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

Opens each hotel and adds the price from every booking site (Booking.com, Expedia, the hotel's own site, ...), plus the street address, phone number and typical price range. Slower, at no extra charge.

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

Language code for hotel descriptions and labels, e.g. en, fr, de, es, pt-BR.

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

Proxy used to reach Google. The default (Apify datacenter proxy, United States) works well; Google hides hotel prices for visitors from some countries.

## Actor input object example

```json
{
  "searchQueries": [
    "hotels in Paris"
  ],
  "maxResults": 20,
  "adults": 2,
  "childrenAges": [],
  "currency": "USD",
  "sortBy": "relevance",
  "minRating": "",
  "hotelClass": [],
  "includeOffers": false,
  "language": "en",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

The scraped hotels as dataset items — one item per hotel, with prices for the requested stay, rating, amenities, location, photos and booking links.

# 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 = {
    "searchQueries": [
        "hotels in Paris"
    ],
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("outspoken_strategy/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 = {
    "searchQueries": ["hotels in Paris"],
    "maxResults": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

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

```

## MCP server setup

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