# Google Hotels Scraper (Reliable, No Browser) (`steadyapi/google-hotels-scraper`) Actor

Scrape Google Hotels search results by city or query: name, price, rating, review count, hotel class, coordinates, website and photos. No browser = lower cost and fewer failures.

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

## Pricing

from $1.40 / 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.
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

Get hotel search results from **Google Hotels** for any city or query: name, nightly price, currency, guest rating, review count, hotel class, coordinates, official website, photos and direct links. Built for price monitoring, travel apps, market research and lead lists.

### Why this one

- **No headless browser.** Results are read straight from the page data Google already ships, so runs finish in seconds and cost less.
- **Retries that understand Google.** Consent pages, "unusual traffic" pages and empty pages are detected and retried on a fresh proxy session instead of being returned as success.
- **Automatic proxy fallback.** Starts on standard Apify Proxy and switches to residential proxies only when Google starts blocking.
- **Partial success over total failure.** One bad query never kills the run. Failed queries come back as rows with `error` and `errorType`.
- **Run summary you can assert on.** Every run writes `RUN_SUMMARY` with requested / succeeded / failed counts.

### Input

| Field | Description |
|---|---|
| `queries` | Cities or full queries, one per line: `Tokyo`, `hotels in paris`, `boutique hotels in Soho London` |
| `checkIn` / `checkOut` | `YYYY-MM-DD`. Empty = 14 days from today, one night |
| `country` | Sets the currency. Google prices in the visitor's local currency, so the Actor searches from this country (US = USD, GB = GBP, DE = EUR, JP = JPY...) |
| `language` | Interface language, default `en` |
| `maxHotelsPerQuery` | Up to 20 (the first result page) |
| `maxPhotos` | Photo URLs per hotel |

### Output (one row per hotel)

```json
{
  "name": "Hotel Relais Du Louvre",
  "position": 3,
  "type": "hotel",
  "rating": 4.8,
  "reviewCount": 812,
  "starClass": 3,
  "price": 289,
  "priceDisplay": "$289",
  "currency": "USD",
  "checkIn": "2026-10-10",
  "checkOut": "2026-10-12",
  "latitude": 48.8592,
  "longitude": 2.3410,
  "website": "https://...",
  "googleHotelsUrl": "https://www.google.com/travel/hotels/entity/...",
  "googleMapsUrl": "https://maps.google.com/?cid=...",
  "ratingBreakdown": { "stars5": 640, "stars4": 120, "stars3": 30, "stars2": 10, "stars1": 12 },
  "reviewTopics": [{ "topic": "Location", "mentions": 210, "positive": 198, "negative": 6 }],
  "nearbyPlaces": [{ "name": "Louvre Museum", "travelTime": "4 min", "transport": null }],
  "photos": ["https://lh3.googleusercontent.com/..."],
  "query": "hotels in paris",
  "error": null,
  "errorType": null
}
```

Error rows keep the same shape with `error` and `errorType` set: `BLOCKED`, `NO_RESULTS`, `PARSE_ERROR`, `REQUEST_FAILED`.

### Use cases

- Hotel rate monitoring and revenue management
- Travel apps, price comparison and deal alerts
- Market research on hotel supply and ratings by city
- Lead lists of hotels with websites and map links

### Pricing

Pay per result. Billing is one result per returned row, including rows that carry an `error`. Platform usage (compute and proxies) is included.

### Notes

- Prices are the rates Google displays for the chosen dates, in the currency of the selected country.
- Amenity names are included when Google shows them in search results (mostly vacation rentals).
- Only public search results are collected. No login, no personal data.

### Code examples

Copy-paste Python and Node examples (zero dependencies) live in [github.com/steadyapi/scrapers](https://github.com/steadyapi/scrapers). The Python one for this Actor is `python/google_hotels.py`.

Minimal call with plain HTTP:

```bash
curl -X POST "https://api.apify.com/v2/acts/steadyapi~google-hotels-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' -d @input.json
```

### Use it from AI agents (MCP)

Add this Actor as a tool in Claude, Cursor or any MCP client through the Apify MCP server:

```text
https://mcp.apify.com/?tools=steadyapi/google-hotels-scraper
```

Authenticate with your Apify token (OAuth is also supported). The agent can then call the Actor directly and read the results.

### FAQ

**Can I get prices for specific dates?**
Yes. Set `checkIn` and `checkOut`. Leave them empty to get a one-night stay two weeks from today.

**Why are prices in USD?**
Google shows prices in the visitor's local currency. Set `country` (GB, DE, JP and so on) to get local-currency prices.

**How many hotels per search?**
Up to 20 per query, which is Google's first result page. Add more specific queries (neighborhoods, landmarks, hotel types) to cover a city.

**Is this the same data as Google Maps?**
It is the Google Hotels view: prices, hotel class, rating breakdown and review topics. Each row also links to the Google Maps listing.

# Actor input Schema

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

One entry per line. A city (Tokyo), a full query (hotels in paris) or a neighborhood (boutique hotels in Soho London). City names are searched as 'hotels in <city>'.

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

YYYY-MM-DD. Leave empty to use 14 days from today (UTC).

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

YYYY-MM-DD. Leave empty for a one-night stay after check-in.

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

Google shows prices in the currency of the visitor's country, so the Actor searches through a proxy in this country. US = USD, GB = GBP, DE/FR/ES/IT = EUR, JP = JPY, CA = CAD, AU = AUD, IN = INR.

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

Interface language code for text fields such as descriptions and amenity names, for example en, de, fr, es.

## `maxHotelsPerQuery` (type: `integer`):

Maximum number of hotels returned for each query. The first result page holds about 20 hotels.

## `maxPhotos` (type: `integer`):

How many photo URLs to include for each hotel. Set 0 to skip photos.

## `requestDelayMs` (type: `integer`):

Pause between queries. Higher values are gentler on Google and reduce retries.

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

Defaults to Apify Proxy. If Google starts blocking, the Actor switches to residential proxies automatically. The proxy country is set from the Country field unless you choose one here.

## Actor input object example

```json
{
  "queries": [
    "hotels in paris"
  ],
  "country": "US",
  "language": "en",
  "maxHotelsPerQuery": 10,
  "maxPhotos": 3,
  "requestDelayMs": 1000,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Name, price, currency, rating, review count, hotel class, amenities, coordinates, website, photos and links for every hotel.

## `runSummary` (type: `string`):

requested / succeeded / failed / successRate, hotels collected, retries, dates used and proxy sessions.

# 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"
    ],
    "country": "US",
    "maxHotelsPerQuery": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadyapi/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"],
    "country": "US",
    "maxHotelsPerQuery": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

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

```

## MCP server setup

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