# Google Hotels Scraper — OTA Prices, Rate Parity & Hotel Search (`jhon_snow/google-hotels-rate-shopper`) Actor

Google Hotels scraper for hotel prices: every OTA rate (Booking.com, Expedia, Agoda, Hotels.com, Trip.com and 30+ more) plus the official site, for any hotel list and date range, with the rate-parity gap per date. Also hotel search listings. Fast HTTP scraper, pay per result, no browser.

- **URL**: https://apify.com/jhon\_snow/google-hotels-rate-shopper.md
- **Developed by:** [Ivan Oscar Niglia](https://apify.com/jhon_snow) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 rate snapshots

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Google Hotels Scraper — OTA Prices, Rate Parity & Hotel Search

Get **every OTA price Google Hotels shows for a hotel** (Booking.com, Expedia, Agoda, Hotels.com, Trip.com, the hotel's official site and 30+ more) for **any list of hotels and any range of dates**, in one run. Each row tells you the lowest price, who has it, the official-site price and the **rate-parity gap**.

Built for hotel revenue managers, hotel consultants, travel agencies and anyone building price-comparison or rate-monitoring tools. Commercial rate-shopping tools charge hundreds of dollars a month for the same data, and the other parity Actors on this Store charge $0.01 per parity row or bill each OTA line separately — which on a 27-source hotel adds up to about $0.058 per hotel-date. This one is **$0.005 per hotel-date, the full OTA ladder included**.

- **Comp-set rate calendar**: 5 hotels × 30 check-in dates = 150 price ladders in about a minute.
- **Rate parity**: official site vs. cheapest OTA, as a percentage, per date.
- **Any market and currency**: prices as seen from any country (point of sale), in any currency.
- **Hotel search listings**: name, stars, rating, review count, coordinates, lowest price for any query.
- **HTTP-only**: no browser, so runs are fast and cheap. Each price is checked against the dates you asked for before it's saved.

### What you get

#### Rate snapshot (one per hotel × check-in date)

Real output from a test run on 11 Sept 2026:

```json
{
  "type": "rate",
  "hotelName": "Hilton Buenos Aires",
  "checkIn": "2026-11-08",
  "checkOut": "2026-11-10",
  "nights": 2,
  "adults": 2,
  "currency": "USD",
  "priceBasis": "beforeTaxes",
  "lowestPrice": 286.61,
  "lowestPriceSource": "pricetravel.com",
  "officialSitePrice": 329,
  "lowestOtaPrice": 286.61,
  "lowestOtaSource": "pricetravel.com",
  "parityGapPct": 12.9,
  "sourcesCount": 27,
  "available": true,
  "offers": [
    {
      "source": "Hilton Buenos Aires",
      "isOfficialSite": true,
      "nightly": 329,
      "nightlyWithTaxes": 398.08,
      "totalStay": 658,
      "totalStayWithTaxes": 796.16,
      "display": "$329",
      "freeCancellationUntil": "Nov 6"
    },
    {
      "source": "pricetravel.com",
      "isOfficialSite": false,
      "nightly": 286.61,
      "nightlyWithTaxes": 332,
      "totalStay": 573.22,
      "totalStayWithTaxes": 664,
      "display": "$287",
      "freeCancellationUntil": "Nov 6"
    }
  ],
  "stars": 5,
  "rating": 4.6,
  "reviewsCount": 21037,
  "address": "Macacha Güemes 351, C1106BKG Cdad. Autónoma de Buenos Aires, Argentina",
  "googleHotelsUrl": "https://www.google.com/travel/hotels/entity/ChYI1PSdirWY8qI5GgovbS8wNjRtYjBnEAE"
}
```

#### Search listing (one per hotel in the results)

`name`, `position`, `stars`, `rating`, `reviewsCount`, `latitude`, `longitude`, `phone`, `website`, `checkInTime`, `checkOutTime`, `description`, `lowestPrice {nightly, nightlyTaxes, nightlyWithTaxes, currency}`, `hotelId`, `googleHotelsUrl`.

### How to use

**Rate calendar for your comp set**

```json
{
  "hotels": ["Hilton Buenos Aires", "Alvear Palace Hotel Buenos Aires", "Four Seasons Hotel Buenos Aires"],
  "checkIn": "2026-11-01",
  "nights": 1,
  "daysToScan": 30,
  "currency": "USD",
  "country": "us"
}
```

**Every Friday for the next 3 months**

```json
{ "hotels": ["Hotel Arts Barcelona"], "checkIn": "2026-10-02", "daysToScan": 90, "stepDays": 7, "nights": 2, "currency": "EUR", "country": "es" }
```

**Market listing with prices**

```json
{ "searchQueries": ["5 star hotels in cancun"], "checkIn": "2026-12-20", "nights": 3, "includeOtaPrices": true }
```

Tips:

- Put the city in the hotel name ("Park Hyatt Mendoza", not "Park Hyatt"). Check the `hotelName` column to confirm the match, or paste the Google Hotels URL to be exact.
- `country` changes the prices: OTAs price differently by market. Use the country your guests book from.
- Comparisons use the **pre-tax nightly rate** by default, because every source reports it. Tax-inclusive prices vary by OTA and market (some drop local VAT). Set `priceBasis` to `withTaxes` if you need the all-in price; the two are never mixed in one comparison.

### Pricing (pay per event)

| Event | Price |
|---|---|
| Rate snapshot (hotel × date with the full OTA ladder) | $0.005 |
| Hotel listing (one hotel from a search) | $0.003 |

A 5-hotel, 30-day rate calendar costs **$0.75**. Sold-out dates and hotels with no prices are still saved with `available: false`, but they are **not charged**.

### Limits

- Search queries return Google's first page (about 20 hotels). For more coverage, use narrower queries (by neighborhood or star rating).
- Prices are what Google Hotels shows at the moment of the run. Some sources show member or mobile rates only after sign-in; those aren't included.
- Up to 180 check-in dates per run, stays of 1–30 nights, 1–8 adults.

### Support

Open an issue on the Actor page. Replies in English or Spanish.

***

### En español

Precios de **todas las OTAs** que muestra Google Hotels (Booking, Expedia, Agoda, sitio oficial y 30+ más) para **tu set de hoteles competidores** en **cualquier rango de fechas**, con la **brecha de paridad** entre el sitio oficial y la OTA más barata. Pensado para revenue managers, consultores hoteleros y agencias. Cargá nombres de hoteles con la ciudad o URLs de Google Hotels, elegí la fecha de check-in, cuántos días escanear, la moneda y el país de venta. Cobra US$0,005 por snapshot de tarifas y US$0,003 por hotel listado. Las fechas sin precios no se cobran.

# Actor input Schema

## `hotels` (type: `array`):

Hotel names with the city ("Hilton Buenos Aires") or Google Hotels URLs (https://www.google.com/travel/hotels/entity/...). For each hotel and date you get one rate snapshot with every OTA price.

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

Free-text Google Hotels searches, e.g. "hotels in palermo buenos aires" or "5 star hotels in cancun". Results are paginated automatically until "Max hotels per query" is reached.

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

First check-in date, YYYY-MM-DD. Defaults to 14 days from today.

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

Length of stay (1–30).

## `daysToScan` (type: `integer`):

How many consecutive check-in dates to price, starting at the check-in date. 30 = a full month rate calendar.

## `stepDays` (type: `integer`):

Days between scanned check-in dates. 7 = the same weekday every week.

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

Number of adult guests (1–8). OTA prices depend on occupancy.

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

ISO currency code for all prices (USD, EUR, GBP, ARS, BRL, MXN...).

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

2-letter country the prices are shown for. OTAs price differently by market, so use your guests' country.

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

Language for hotel names and texts (en, es, pt, fr...).

## `includeOtaPrices` (type: `boolean`):

For search queries, also fetch the full OTA price ladder of every listed hotel (one rate snapshot each). Hotels in the "hotels" list always get it.

## `priceBasis` (type: `string`):

Which price to compare for lowest price and parity gap. Pre-tax is consistent across all sources; tax-inclusive prices vary by OTA and market (some drop local VAT).

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

How many hotels to keep from each search query and date. Google returns about 18-20 per page, so anything above that pages through the results automatically (20 = 1 page, 100 = about 5 pages). Duplicates across pages are removed.

## `includeBookingLinks` (type: `boolean`):

Add the Google redirect link of each offer. Off by default to keep the dataset small.

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

Datacenter proxies work well. Switch to residential only if you see BLOCKED warnings in the log.

## Actor input object example

```json
{
  "hotels": [
    "Hilton Buenos Aires",
    "Alvear Palace Hotel Buenos Aires"
  ],
  "nights": 1,
  "daysToScan": 1,
  "stepDays": 1,
  "adults": 2,
  "currency": "USD",
  "country": "us",
  "language": "en",
  "includeOtaPrices": false,
  "priceBasis": "beforeTaxes",
  "maxHotelsPerQuery": 20,
  "includeBookingLinks": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `runStats` (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 = {
    "hotels": [
        "Hilton Buenos Aires",
        "Alvear Palace Hotel Buenos Aires"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("jhon_snow/google-hotels-rate-shopper").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 = {
    "hotels": [
        "Hilton Buenos Aires",
        "Alvear Palace Hotel Buenos Aires",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("jhon_snow/google-hotels-rate-shopper").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 '{
  "hotels": [
    "Hilton Buenos Aires",
    "Alvear Palace Hotel Buenos Aires"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call jhon_snow/google-hotels-rate-shopper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jhon_snow/google-hotels-rate-shopper"
        }
    }
}
```

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/j3cdhiQa7jF4bWEXg/builds/WrwPccymeLqoQYVbr/openapi.json
