# Google Hotels Scraper: Prices, OTA Rates, Ratings & Amenities (`varnmill/google-hotels-scraper`) Actor

Scrape Google Hotels for any destination and dates: nightly and total prices with taxes, the full price ladder per hotel (Booking.com, Expedia, Agoda, official site and more with direct links), ratings, reviews, amenities, address, phone and location. No login, no browser.

- **URL**: https://apify.com/varnmill/google-hotels-scraper.md
- **Developed by:** [Jay Novello](https://apify.com/varnmill) (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

from $1.50 / 1,000 hotels

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: Prices, OTA Rates, Ratings & Amenities

Scrape **Google Hotels** for any destination and dates as clean JSON, CSV or Excel. You get nightly and total prices before and after taxes, deal badges, star class, guest ratings, review counts, amenities, location and nearby places. Optionally add the full **price ladder** for each hotel: every booking site's price (Booking.com, Expedia, Agoda, Hotels.com, the hotel's own site and more) with a direct booking link. No login, no browser, no API key. **$1.50 per 1,000 hotels**, plus $1.25 per 1,000 for the price ladder.

### Real example

Run on Apify on **October 13, 2026 (20:05 UTC)**. Search mode, query `hotels in New York`, check-in 30 days ahead (Nov 12 to 14, 2026, 2 nights, 2 adults, USD), 3 hotels, price ladder on. It finished in 8 seconds and cost the user $0.008.

| # | Hotel | Class | Rating (reviews) | Per night | Total with taxes | Booking sites | Cheapest site (total) |
|---|---|---|---|---|---|---|---|
| 1 | The Times Square EDITION | 5-star | 4.4 (1,823) | $399.73 | $924.47 | 32 | KAYAK.com ($924.47) |
| 2 | 31 Street Broadway Hotel | 3-star | 2.6 (444) | $61.23 | $590.53 | 14 | Hotel Booking Zone ($516.09) |
| 3 | The Brooklyn Riviera Hostel | 3-star | 4.0 (181) | $75.00 | $185.75 | 1 | Booking.com ($185.75) |

Row 2 is why the ladder is sorted by what the guest actually pays: Google's headline price was $61 a night, but taxes and fees took the stay to $590.53.

Same day, hotels mode, input `The Plaza New York`, two check-in dates, 2 nights each:

| Check-in | Booking sites | Cheapest total with taxes | Next cheapest | Paid ads by |
|---|---|---|---|---|
| 2026-11-12 | 22 | The Plaza (official site) $4,547.75 | Skyscanner $4,562.00 | Hotels.com, The Plaza, Priceline, KAYAK.com |
| 2026-11-19 | 19 | The Plaza (official site) $4,639.50 | Skyscanner $4,654.00 | Hotels.com, The Plaza, Priceline |

One full row from the search run (shortened: 2 of 9 review topics, 2 of 6 nearby places, booking URL cut):

```json
{
  "type": "hotel",
  "searchQuery": "hotels in New York",
  "position": 1,
  "name": "The Times Square EDITION",
  "hotelId": "ChkImse_0eKv8eE-Gg0vZy8xMWcwbXY4c19oEAE",
  "propertyType": "hotel",
  "hotelClass": "5-star hotel",
  "stars": 5,
  "rating": 4.4,
  "reviewCount": 1823,
  "ratingDistribution": {"1": 113, "2": 53, "3": 96, "4": 239, "5": 1322},
  "reviewTopics": [
    {"topic": "Bar or lounge", "mentions": 160, "sentiment": 0.45},
    {"topic": "Service", "mentions": 478, "sentiment": 0.48}
  ],
  "pricePerNight": 399.73,
  "pricePerNightWithTaxes": 462.24,
  "totalPrice": 799.46,
  "totalPriceWithTaxes": 924.47,
  "taxesAndFees": 125.01,
  "currency": "USD",
  "dealBadge": "27% less than usual",
  "checkInDate": "2026-11-12",
  "checkOutDate": "2026-11-14",
  "nights": 2,
  "adults": 2,
  "address": "701 7th Ave, New York, NY 10036",
  "phone": "(212) 398-7017",
  "website": "https://www.marriott.com/en-us/hotels/nycte-the-times-square-edition/overview/?scid=f2ae0541-1279-4f24-b197-a979c79310b0",
  "latitude": 40.759149,
  "longitude": -73.984164,
  "checkInTime": "4:00 PM",
  "checkOutTime": "11:00 AM",
  "amenities": ["Free Wi-Fi", "Air conditioning", "Pet-friendly", "Fitness center", "Breakfast", "Parking", "Bar",
                "Restaurant", "Room service", "Accessible", "Kid-friendly", "Smoke-free property"],
  "nearbyPlaces": [
    {"category": "attraction", "name": "Times Square", "travel": [{"mode": "walking", "duration": "1 min"}]},
    {"category": "transit", "name": "49 St", "travel": [{"mode": "walking", "duration": "3 min"}]}
  ],
  "offerCount": 32,
  "lowestOffer": {
    "source": "KAYAK.com",
    "isOfficialSite": false,
    "pricePerNight": 399.73,
    "pricePerNightWithTaxes": 462.23,
    "totalPrice": 799.47,
    "totalPriceWithTaxes": 924.47,
    "pricePerNightDisplay": "$400",
    "totalPriceWithTaxesDisplay": "$924",
    "bookingUrl": "https://www.kayak.com/semi/ha/hotel_ads/900265/en.html?utm_source=google&utm_med..."
  },
  "googleMapsUrl": "https://www.google.com/maps?cid=11787536364984421983",
  "scrapedAt": "2026-10-13T20:05:23Z"
}
```

The full row also has `offers` (all 32 sites in the same format as `lowestOffer`), `sponsoredSources`, `description`, `images`, `thumbnail`, `amenityCodes`, `placeId`, `googleCid`, `featureId` and `googleHotelsUrl`.

### What it does

- **Search mode**: type anything you would type into Google Hotels ("hotels in Paris", "Tokyo Shinjuku", "resorts in Cancun", "pet friendly hotels in Austin"). You get Google's list in order with the lowest price for your dates. It pages through automatically up to `maxHotelsPerQuery`.
- **Hotels mode (rate shopping)**: give Google Hotels URLs, hotel IDs from an earlier run, or plain names such as "Ritz Paris". For each hotel you get every booking site's price, the hotel's own site flagged with `isOfficialSite`, which sites run paid ads for it, plus address, phone and Google place ID.
- **Price calendar**: add several check-in dates (`checkInDates`) to price the same hotels or queries across dates in one run.
- **Scheduling**: leave the date empty and set `daysFromToday` and `nights`. A daily schedule then always prices, for example, "two nights starting 30 days from today".
- **Any market**: set `currency` (USD, EUR, GBP, JPY...), `country` (the market Google prices for) and `language`.
- **Filters**: minimum guest rating, minimum stars, maximum nightly price and "hotels only" (no vacation rentals). Hotels removed by a filter are not charged.
- **Minimum stays**: when a hotel has no price for your dates (often a minimum-stay rule), the row includes `suggestedStay`, the stay Google offers instead.

### Input examples

Search, 50 hotels, 4.0+ rating, 2 nights starting 3 weeks from the run date:

```json
{"mode": "search", "queries": ["hotels in Barcelona"], "maxHotelsPerQuery": 50, "minRating": "4", "daysFromToday": 21, "nights": 2}
```

Rate shopping for a competitor set over four Fridays, in euros:

```json
{"mode": "hotels", "hotels": ["Hotel Regina Louvre Paris", "Le Meurice Paris", "https://www.google.com/travel/hotels/entity/ChUImcGKtLfWgL9OGgkvbS8wNTZuODEQAQ"],
 "checkInDates": ["2026-11-06", "2026-11-13", "2026-11-20", "2026-11-27"], "nights": 1, "currency": "EUR", "country": "fr"}
```

### Pricing

Pay per event. Platform usage is included, so you pay only for results.

| Event | Price | When |
|---|---|---|
| `hotel` | $0.0015 ($1.50 per 1,000) | Each hotel row delivered |
| `ota-prices` | $0.00125 ($1.25 per 1,000) | Each hotel row that includes a price ladder with at least one offer (hotels mode, or search with `includeOtaPrices`) |
| Actor start | $0.00005 | Once per run |

Examples: 1,000 hotels from search costs $1.50. 1,000 hotels with every booking site's price costs $2.75. Error rows, filtered-out hotels and hotels without any offer are not charged for the ladder. Set a maximum charge on the run and the actor stops cleanly when it is reached.

### Accuracy and limits

- Prices are exactly what Google Hotels shows for the chosen market, currency, dates and number of adults at the moment of the run. They change constantly; schedule runs to track them.
- `pricePerNight` and `totalPrice` exclude taxes, as Google's default view does. `...WithTaxes` fields include taxes and fees. `taxesAndFees` is the difference.
- Search results contain about 20 hotels per page. Google lists sponsored hotels separately; this actor returns the organic list and skips duplicates across pages.
- Name matching in hotels mode uses Google's top match. Check `matchedName`. If Google's match shares no distinctive word with your input, the actor returns an error row instead of guessing.
- Child guests and multiple rooms are not supported yet; prices are for one room with the given adults.
- Amenity names are always in English. Other text (descriptions, hotel class) follows `language`.
- Booking URLs come from Google's free booking links. Paid ad click links are left out on purpose; `sponsoredSources` only names who is advertising.

### Reliability

The actor reads the data Google embeds in its own Hotels pages with plain HTTP requests. No browser, so runs are fast (about 1 to 3 seconds per page). It sends a consent cookie so EU pages never show the "Before you continue" screen. If Google rate-limits a direct connection, it retries with backoff and switches to the Apify datacenter proxy on its own. In tests on October 13, 2026: 360 hotels across six cities in 49 seconds from 25 requests with no retries, and 60 hotels with 56 price ladders in 37 seconds.

### FAQ

**Do I need a Google account, API key or proxy?** No.

**Can I monitor one hotel's price every day?** Yes. Use hotels mode with its URL or `hotelId`, leave the check-in date empty, set `daysFromToday` and `nights`, and schedule the actor daily.

**Why does a hotel have no price?** It has no availability for those dates, or a minimum stay applies. See `suggestedStay`.

**Why is the cheapest site sometimes not the lowest nightly price?** Sites differ in taxes and fees. The ladder is sorted by total with taxes, which is what the guest pays.

**Does it return reviews text?** No. It returns rating, review counts per star and review topics with a sentiment score. Review text may come in a later version.

**What does `hotelId` look like and where else can I use it?** It is Google's entity ID (for example `ChkImse_0eKv8eE-Gg0vZy8xMWcwbXY4c19oEAE`). Put it in hotels mode to re-price the same hotel. `googleHotelsUrl` opens the hotel on Google with your dates.

### Changelog

- 0.1 (2026-10-13): First release. Search and hotels modes, price ladder with direct booking links, price calendar, relative dates, filters, minimum-stay suggestions, automatic proxy fallback.

# Actor input Schema

## `mode` (type: `string`):

'search' returns the hotels Google lists for each query, with the lowest price. 'hotels' opens specific hotels (Google Hotels URLs, hotel IDs or hotel names) and returns every booking site's price for each.

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

What you would type into Google Hotels, for example 'hotels in Paris', 'Tokyo Shinjuku', 'resorts in Cancun' or 'pet friendly hotels in Austin'. One result list per query and date.

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

Google Hotels URLs (anything containing /entity/...), hotel IDs from a previous run (the 'hotelId' field), or plain hotel names with a city such as 'Ritz Paris'. Names are matched to Google's first result; check 'matchedName' in the output.

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

Check-in date (YYYY-MM-DD). Leave empty to use 'Days from today', which keeps scheduled runs pointing at a future date.

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

Check-out date (YYYY-MM-DD). Used only with a single check-in date; otherwise 'Nights' decides the stay length.

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

Extra check-in dates (YYYY-MM-DD) to price the same queries or hotels across several dates in one run, each for 'Nights' nights. Useful for rate shopping and price calendars.

## `daysFromToday` (type: `integer`):

When no check-in date is set, check in this many days after the run date (0 = today).

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

Length of stay in nights when no check-out date is given.

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

Number of adult guests (prices change with occupancy).

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

Three-letter currency code for all prices, for example USD, EUR, GBP, JPY, AUD.

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

Stop after this many hotels for each query and date. Google shows about 20 per page; the actor pages through as needed.

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

Also open each hotel's page and add every booking site's price (Booking.com, Expedia, Agoda, official site...) with direct links, plus address and phone. Charged as an extra 'ota-prices' event per hotel. Always on in hotels mode.

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

Skip hotels rated below this (Google's 1 to 5 guest rating). Skipped hotels are not charged.

## `minStars` (type: `integer`):

Skip hotels below this star class (0 = any). Vacation rentals have no class and are skipped when this is above 0.

## `maxPricePerNight` (type: `integer`):

Skip hotels whose nightly price before taxes is above this, in the chosen currency (0 = no limit). Hotels without a price for your dates are skipped when this is set.

## `excludeVacationRentals` (type: `boolean`):

Google mixes vacation rentals into hotel results; tick to keep hotels only.

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

Google interface language code (hl), for example en, fr, de, es, ja. Affects hotel descriptions and labels.

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

Two-letter country code (gl) for the market Google prices for, for example us, gb, de, au. Booking sites and prices can differ by market.

## `maxConcurrency` (type: `integer`):

How many Google pages to load at the same time. Keep low (2 to 4) to avoid rate limits.

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

Not needed in most cases: the actor connects directly and switches to the Apify datacenter proxy on its own if Google rate-limits it. Set a proxy here to force one.

## `autoProxyFallback` (type: `boolean`):

Switch to the Apify datacenter proxy automatically when Google refuses direct requests.

## Actor input object example

```json
{
  "mode": "search",
  "queries": [
    "hotels in Paris"
  ],
  "daysFromToday": 14,
  "nights": 1,
  "adults": 2,
  "currency": "USD",
  "maxHotelsPerQuery": 20,
  "includeOtaPrices": false,
  "minRating": "0",
  "minStars": 0,
  "maxPricePerNight": 0,
  "excludeVacationRentals": false,
  "language": "en",
  "country": "us",
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "autoProxyFallback": true
}
```

# Actor output Schema

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

No description

## `hotelsCsv` (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 = {
    "queries": [
        "hotels in Paris"
    ]
};

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

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

```

## MCP server setup

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