# Google Hotels Scraper: Hotels, Ratings & Prices by Booking Site (`quarra/google-hotels-scraper`) Actor

Google Hotels scraper for a search (hotels in Paris), a hotel name or a Google Hotels link: name, address, stars, rating, reviews, phone, website and, for your dates, the price on every booking site (Booking.com, Expedia, Agoda...) with the cheapest named.

- **URL**: https://apify.com/quarra/google-hotels-scraper.md
- **Developed by:** [Quarra Labs](https://apify.com/quarra) (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.80 / 1,000 hotel with all its booking-site 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

## Google Hotels Scraper: Hotels, Ratings & Prices by Booking Site

Hotels from Google Hotels: search a city ("hotels in Paris") or give hotel names or Google Hotels links, and get name,
address, coordinates, phone, stars, rating, reviews and, for your dates, the lowest price Google shows. Add the price
of every booking site (Booking.com, Expedia, Agoda, the hotel's own site and more) with the cheapest one named. No
account, no API key. Export as JSON, CSV or Excel, or read it through the Apify API.

**$2.50 per 1,000 hotels** in a plain list, **$4 per 1,000 hotels** with every booking site's price included (or
**$0.20 per 1,000 rows** with one row per site), plus a start fee of $0.002 per run. Hotels without a price and inputs that
fail are not charged.

### Quick start

1. Add a search such as `hotels in paris`, or hotel names, in **Search queries** / **Hotels**.
2. Pick the **Check-in date** and the number of **Nights**.
3. Click **Start** and read the hotels in the run's **Output** tab.

Run it every day on the same dates and cities (Apify schedules) to follow how prices move. Like any Apify Actor, it can
also be run through the Apify API and connected to webhooks, Make, Zapier, n8n or Apify's MCP server for AI agents.

### What it is used for

- **Price monitoring**: which booking site is the cheapest for a hotel, and how the gap moves before your dates.
- **Rate parity checks**: is the hotel's own site as cheap as the resellers?
- **Market snapshots**: the prices, ratings and stars of the hotels Google lists for a city, a district or a landmark.

To compare booking sites only, use
[Google Hotels Prices Scraper](https://apify.com/quarra/google-hotels-prices-scraper).

### What you get

| | |
|---|---|
| Hotel name, Google Hotels ID and page, address, latitude, longitude, phone, website | yes |
| Star rating, guest rating, number of reviews | yes |
| Check-in, check-out, nights, adults, currency | yes |
| Price per night and for the stay on each booking site, taxes and fees included, cheapest first | yes |
| The same before taxes and fees, when Google shows it apart | yes |
| Cheapest site, its price per night and for the stay | yes |
| Whether a site is the hotel's own site | yes |
| Room type, when Google shows it | yes |
| Link that opens the offer | yes |

### Inputs

- **Search queries**: what you would type in Google Hotels (`hotels in paris`, `hotels near eiffel tower`). Each search
  returns the first 18 hotels Google lists; **Max hotels per search** lowers that.
- **Hotels**: a hotel name with its city (`Hotel Astoria Paris`) or the address of the hotel's page on Google Hotels. A
  name is looked up in Google's results and delivered only when exactly one hotel carries **every word** you typed:
  the hotel's own words in its name, the city in its name, its address or the city it stands in (`Hotel Astoria
  Paris`: "Astoria" in the name, in Paris; `Hotel Artemide Rome` is found although its address says "Roma"). A hotel
  of the same name in another city is never taken for it. No hotel matches: a free `hotel_not_found` record; several hotels
  match (`Novotel Paris`): a free `ambiguous_hotel` record that names them. For an exact hotel, paste its Google Hotels
  link. The same hotel given in several forms (name, link, ID) is delivered once.
- **Check-in date**, **Nights** (or **Check-out date**), **Adults** (1 to 6): the prices are for these dates and guests.
  Prices taken from a hotel list are for 2 adults, as Google lists them: each record's `adults` says which count its price is for.
  Dates can be absolute (`2026-12-10`) or relative (`30 days`). Google shows prices up to about 11 months ahead.
- **Prices by booking site**: not included (hotel list only, the default), inside each hotel record in an `offers` list, or one row per hotel and booking site. A hotel given by its Google Hotels link needs one of the last two.
- **Max results**: the exact number of charged results the run delivers.

Prices are those of the **US market** (US dollars, `gl=us`): the same for every run, wherever it runs.

Example, through the API:

```json
{
  "searchQueries": ["hotels in paris"],
  "checkInDate": "2026-12-10",
  "nights": 2,
  "adults": 2,
  "sitePrices": "inRow",
  "maxHotelsPerSearch": 10
}
```

### Output

One record per hotel in the dataset. A shortened record:

```json
{
  "type": "hotelPrices",
  "status": "ok",
  "hotelName": "Hôtel Astoria - Astotel",
  "hotelId": "ChcI__T4uJipguN_GgsvZy8xdGpkbDFyXxAB",
  "address": "42 Rue de Moscou, 75008 Paris, France",
  "rating": 4.3,
  "reviewCount": 1520,
  "checkIn": "2026-12-10",
  "checkOut": "2026-12-12",
  "nights": 2,
  "adults": 2,
  "currency": "USD",
  "taxesAndFeesIncluded": true,
  "offerCount": 20,
  "cheapestProvider": "Booking.com",
  "cheapestPricePerNight": 185.61,
  "cheapestTotalPrice": 371.22,
  "offers": [
    {"provider": "Booking.com", "isOfficialSite": false, "pricePerNight": 185.61, "totalPrice": 371.22,
     "pricePerNightBeforeTaxes": 155.05, "totalPriceBeforeTaxes": 310.11, "link": "https://…"},
    {"provider": "Bluepillow.com", "isOfficialSite": false, "pricePerNight": 190.4, "totalPrice": 380.8,
     "pricePerNightBeforeTaxes": null, "totalPriceBeforeTaxes": null, "link": "https://…"}
  ],
  "input": "hotels in paris",
  "inputType": "search",
  "position": 1,
  "scrapedAt": "2026-10-17T07:00:00.000Z"
}
```

Fields that need a word of explanation:

- `status`: `ok` (delivered, charged), `noPrices` (free: no booking site shows a price for these dates), `error` (free;
  `error` says why, `retryable` says if a later run may work).
- `pricePerNight`, `totalPrice`, `cheapest…`: taxes and fees **included**, as Google shows them "with taxes + fees"
  (`taxesAndFeesIncluded: true`). `pricePerNightBeforeTaxes` and `totalPriceBeforeTaxes` hold the price before taxes
  and fees when Google shows it apart; they are null for a site that gives Google one all-in price.
- `currency`: the currency of every price in the record, as Google shows it. Some booking sites open in their own
  currency (a site billing in euros, for example) and convert there.
- `lowestPricePerNight`, `lowestTotalPrice` (hotel lists): the lowest price per night and for the whole stay across
  booking sites for your dates, taxes and fees included, rounded to the whole dollar as Google writes it in its list
  (exact when the hotel's page was read: hotels given by name, or a list Google answered for other dates); the
  `…BeforeTaxes` fields hold the same before taxes and fees. A hotel without a price for your dates is a free
  `noPrices` record. Exact prices per site come with **Prices by booking site**.
- `link`: opens the offer on the booking site, through Google.

The run summary (counts, dates, why the run stopped) is the `OUTPUT` record of the run's key-value store.

### Pricing

Pay per event:

| Event | Price |
|---|---|
| Hotel in a list (lowest price only) | $2.50 per 1,000 |
| Hotel with all its booking-site prices | $4.00 per 1,000 |
| Booking-site row (one row per hotel and site) | $0.20 per 1,000 |
| Run start | $0.002 per GB of memory (1 GB minimum; $0.002 at the default 256 MB) |

Higher Apify plans pay less per result. Never charged: hotels without a price, error records, a hotel listed more than
once. Set **Maximum cost per run** in the run options and the run stops before going over it.

### Limits

- Prices for the US market only, in US dollars.
- A search returns the first 18 hotels Google lists; for more hotels, search by district or give hotel names.
- Google changes what it shows from one moment to the next: two runs a few minutes apart can differ by a few cents or a site.
- A hotel given by name can be missing from Google's results that minute (Google varies them), and a name with a word
  that is neither in the hotel's name nor in its address (`Hotel Astoria Paris 9e`) is not taken: the record is free,
  and the Google Hotels link always works.
- Google answers any search with hotels, even a nonsense one: check the `searchQuery` and `address` of what you receive.
- A hotel link that leads to no hotel is a free `hotel_not_found` record; a hotel Google shows only for other
  dates or guests than yours is a free `other_dates` record, never delivered under your dates.
- Connection, currency, language or country settings are not used: every run reads the US market through the
  standard connection, and the run's notes say so.

### FAQ

**Do I need a Google account?** No.

**Can I get prices in euros or for another country?** Not yet: prices are for the US market.

**Are taxes and fees included?** Yes: every price is the one Google shows with taxes and fees. When Google also shows
the price before taxes and fees, it is in the `…BeforeTaxes` fields.

**What if the run is restarted by the platform (migration or reboot)?** It resumes where it was: hotels already in the
dataset are not delivered or charged again.

**Is it legal?** It collects prices that Google shows to any visitor. Check the rules that apply to your use of the data.

**Does the Actor send anything to Quarra?** Only when a run fails or runs out of time: the Actor, its build, the error type, the line of our code where it happened, and the memory and time the run was given, so we can fix it fast. Never your input, your results, your account or the run ID.

# Actor input Schema

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

What you would type in Google Hotels: a city, a district, a landmark ('hotels in paris', 'hotels near eiffel tower', 'boutique hotels lisbon'). One search = up to 18 hotels.

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

Hotels to look up: a name with its city ('Hotel Astoria Paris'), or the address of a hotel's page on Google Hotels. A name is delivered only when exactly one hotel carries every word you typed (in its name or its city); otherwise a free record says why. Duplicates are delivered once.

## `sitePrices` (type: `string`):

Whether to read the price each booking site shows for your dates. 'Inside each hotel record' = one record per hotel with every site in an 'offers' list; 'One row per booking site' = one row per hotel and site. Hotel links need this set.

## `maxHotelsPerSearch` (type: `integer`):

Hotels read from each search (Google lists 18 per search).

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

A date (2026-12-10) or a relative one ('30 days', '2 weeks'). Never in the past.

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

Length of the stay, used when no check-out date is set.

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

Replaces 'Nights' when set. Must be after the check-in date; a stay is at most 30 nights.

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

Adults the booking-site prices are for. Hotel lists (without site prices) always show the price for 2 adults.

## `maxItems` (type: `integer`):

Total number of charged results the run delivers, counted exactly: hotels, or booking-site rows when you ask for one row per site. Free records (errors, hotels without a price) are not counted.

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

Connection. Keep the default (automatic): other settings are not needed and are not used. Costs are included in the price.

## Actor input object example

```json
{
  "searchQueries": [
    "hotels in paris"
  ],
  "sitePrices": "none",
  "maxHotelsPerSearch": 5,
  "checkInDate": "30 days",
  "nights": 2,
  "adults": 2,
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Every record with all its fields, and free records with the reason.

## `overview` (type: `string`):

One line per hotel: rating, cheapest site, number of sites.

## `summary` (type: `string`):

Counts per input, dates, why the run stopped, errors.

# 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"
    ],
    "maxHotelsPerSearch": 5,
    "checkInDate": "30 days",
    "nights": 2,
    "adults": 2,
    "maxItems": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("quarra/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"],
    "maxHotelsPerSearch": 5,
    "checkInDate": "30 days",
    "nights": 2,
    "adults": 2,
    "maxItems": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("quarra/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"
  ],
  "maxHotelsPerSearch": 5,
  "checkInDate": "30 days",
  "nights": 2,
  "adults": 2,
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call quarra/google-hotels-scraper --silent --output-dataset

```

## MCP server setup

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