# Google Hotels Prices Scraper (`axiomworks/google-hotels-prices-scraper`) Actor

Scrape Google Hotels by search phrase or hotel URL for your dates. Returns nightly and total prices, each booking site's offer with price and link (Booking.com, Expedia, Agoda, Hotels.com and more), rating, star class, address, phone and photos. Built for rate shopping.

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

## Pricing

from $5.85 / 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

## Google Hotels Prices Scraper

### What does Google Hotels Prices Scraper do?

Google Hotels Prices Scraper collects hotel prices from the public Google Hotels pages (the hotel search at google.com/travel). You give it one or more search phrases, such as "hotels in Paris", or direct links to hotel pages, plus your travel dates, number of adults and currency. It returns one clean record per hotel.

Each record holds the nightly price Google shows for your stay and the total price. Every record also includes the list of booking sites that offer the room, each with its own price and a direct booking link, plus the hotel's address and phone number. Records also include star class, guest rating, review count, coordinates, check-in and check-out times, a short description and photos. The record also repeats your dates, currency and adult count, so you always know which stay a price belongs to.

Typical uses:

- **Rate shopping and revenue management.** Hotels and property managers can track what competitors charge on specific dates and see which booking sites undercut the official rate.
- **Travel price comparison.** Build a simple comparison view that shows, for each hotel, which booking site is cheapest for a given stay.
- **Market research.** Measure average prices, star-class mix and rating spread for a city or neighbourhood, then repeat the run on a schedule to watch prices move.
- **Lead lists for the hospitality industry.** Get hotel names, addresses, phone numbers and map coordinates for a destination in one run.
- **AI agents and assistants.** Let an agent answer "What is the cheapest 4-star hotel near the Louvre for 12 to 14 November?" from live data.

The Actor reads the data that Google embeds in its public pages. It does not need a Google account, cookies or any login, and it does not open a browser. That keeps runs fast and cheap. It is an independent tool and is not affiliated with or endorsed by Google.

### What data can you get from Google Hotels?

Every hotel record contains the fields below. Fields that Google does not show for a given hotel (for example, a star class for a holiday apartment) are returned as `null`.

| Field | Description |
|---|---|
| `id` | Stable record ID (the Google Hotels entity ID). Unique within a run. |
| `sourceUrl` | The Google page the record was read from. |
| `entityId` | Google Hotels entity ID of the property. |
| `name` | Hotel or property name. |
| `googleHotelUrl` | Link to the hotel's page on Google Hotels. |
| `query` | The search phrase or hotel URL that produced this record. |
| `position` | Rank of the hotel within its search results (1 = first). |
| `latitude`, `longitude` | Map coordinates. |
| `hotelClass` | Star class as a number, e.g. `4`. `null` for rentals. |
| `hotelClassText` | Star class as shown, e.g. "4-star hotel". |
| `rating` | Average guest rating out of 5. |
| `reviewsCount` | Number of guest reviews. |
| `description` | Short description of the property. |
| `checkInTime`, `checkOutTime` | Check-in and check-out times, e.g. "3:00 PM". |
| `thumbnail` | Main photo URL. |
| `images` | Photo URLs from the listing (usually 8 to 10). |
| `pricePerNight` | Nightly price in your currency, rounded to 2 decimals. When offers exist, it is the cheapest offer's nightly price. |
| `pricePerNightText` | The price as displayed, e.g. "$171". |
| `priceTotal` | Price for the whole stay, rounded to 2 decimals. |
| `currency` | Currency of all prices, e.g. `USD`. |
| `checkIn`, `checkOut` | The stay dates the prices belong to. |
| `adults` | Number of adults the prices are for. |
| `googleMapsFeatureId` | Google Maps feature ID, useful for joining with Google Maps data. |
| `address` | Street address from the hotel page . |
| `phone` | Phone number from the hotel page . |
| `offers` | List of booking sites with `provider`, `pricePerNight`, `priceTotal` and `bookingUrl`. `null` when the hotel page has no offers. |
| `cheapestProvider` | Name of the booking site with the lowest nightly price . |
| `scrapedAt` | Time the record was collected (ISO 8601). |

### How to use Google Hotels Prices Scraper

1. Open the Actor in Apify Console and go to the **Input** tab.
2. In **Search**, type one or more search phrases, such as `hotels in Paris` or `hotels near Times Square`. You can also paste Google Hotels hotel page links into **Hotel URLs** to price specific properties.
3. Set **Maximum hotels per query** to the number of hotels you want for each phrase. Google shows about 20 hotels per results page, and the Actor pages through the results until it reaches your limit or runs out of hotels.
4. In **Stay**, pick the check-in and check-out dates and the number of adults. If you leave the dates empty, the Actor prices a one-night stay starting 7 days from today.
5. In **Currency and language**, set the currency (for example `EUR`) and the interface language (for example `en`).
6. Keep the default residential proxy in **Proxy** unless you have a reason to change it. Google often blocks datacenter IP addresses.
7. Click **Start**. When the run finishes, open the **Output** tab to view the results as a table, or download them as JSON, CSV, Excel or XML.

Tips:

- Every hotel page is opened, so address, phone, per-site offers and the cheapest site are included. `includeOffers` only controls whether the separate hotel-offers event is billed; set it to `false` to skip that event.
- Prices for dates far in the future, or for tomorrow in busy cities, may be missing because hotels are sold out or have not opened their rates. Those hotels are still returned, with price fields set to `null`, and `offers` is empty.
- Use one phrase per area. "hotels in Paris" and "hotels in Paris 11th arrondissement" return different sets of hotels. The Actor removes duplicate hotels within a run.
- To track prices over time, save your input as a task and run it on a schedule. Each record includes `scrapedAt`, `checkIn` and `checkOut`, so runs are easy to compare.

### Input

| Field | Type | Description |
|---|---|---|
| `queries` | array of strings | Search phrases, e.g. `["hotels in Paris"]`. Provide this or `hotelUrls`. |
| `hotelUrls` | array of strings | Google Hotels hotel page URLs, e.g. `https://www.google.com/travel/hotels/entity/ChkI...`. |
| `maxItems` | integer | Maximum hotels per search phrase, 1 to 1000. Default 50. |
| `checkIn` | string | Check-in date, `YYYY-MM-DD`. Default: 7 days from today. |
| `checkOut` | string | Check-out date, `YYYY-MM-DD`, 1 to 30 nights after check-in. Default: one night. |
| `adults` | integer | Number of adults, 1 to 12. Default 2. |
| `currency` | string | ISO 4217 currency code, e.g. `USD`, `EUR`, `GBP`. Default `USD`. |
| `language` | string | Google interface language, e.g. `en` or `de`. Default `en`. |
| `includeOffers` | boolean | Bill the hotel-offers event for hotels with page details. Hotel pages are always opened. Default `false`. |
| `proxyConfiguration` | object | Apify Proxy settings. Default: Apify residential proxies. |

The Actor checks the input before it starts. For example, a date in the wrong format, a check-out before the check-in, or a stay longer than 30 nights stops the run straight away with a clear error message instead of returning empty results.

Example input:

```json
{
    "queries": ["hotels in Paris", "hotels near Times Square"],
    "maxItems": 40,
    "checkIn": "2026-11-12",
    "checkOut": "2026-11-14",
    "adults": 2,
    "currency": "EUR",
    "language": "en",
    "includeOffers": true,
    "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
```

### Output

Results are stored in the run's dataset. Here is a real record from a local test run (photo and offer lists shortened):

```json
{
    "id": "ChkI1N6v0cC4pfmpARoML2cvMTJxNHhyNHh0EAE",
    "sourceUrl": "https://www.google.com/travel/hotels/entity/ChkI1N6v0cC4pfmpARoML2cvMTJxNHhyNHh0EAE/prices?hl=en&ts=CAESDgoCCAMKAggDCgIIAxAAGhgSFhIUCgcI6g8QChgUEgcI6g8QChgWGAIqCQoFOgNHQlAaAA",
    "entityId": "ChkI1N6v0cC4pfmpARoML2cvMTJxNHhyNHh0EAE",
    "name": "Novotel Suites Paris Stade de France",
    "googleHotelUrl": "https://www.google.com/travel/hotels/entity/ChkI1N6v0cC4pfmpARoML2cvMTJxNHhyNHh0EAE",
    "query": "https://www.google.com/travel/hotels/entity/ChkI1N6v0cC4pfmpARoML2cvMTJxNHhyNHh0EAE",
    "position": 1,
    "latitude": 48.923648199999995,
    "longitude": 2.3629501000000004,
    "hotelClass": 4,
    "hotelClassText": "4-star tourist hotel",
    "rating": 4.3,
    "reviewsCount": 1431,
    "description": "Contemporary all-suite lodging with Wi-Fi, a bar & a 24/7 pantry, plus parking.",
    "checkInTime": "4:00 PM",
    "checkOutTime": "12:00 PM",
    "thumbnail": "https://lh3.googleusercontent.com/grass-cs/AABkmLfOSWryWzCIqfEyCyrBUGFB2UmPzU4wAEvy24Wy0trDadO6ropUlz9l1Us-1vdkR1-WQOeiTX6Tc-GNUZXCRGmMvPj-_-_ekXcwfzDxhW9qnnIumQ26wn3b_5kKILQLKSJsZJRS=s150-w92-h150-n-k-no",
    "images": [
        "https://lh3.googleusercontent.com/grass-cs/AABkmLfOSWryWzCIqfEyCyrBUGFB2UmPzU4wAEvy24Wy0trDadO6ropUlz9l1Us-1vdkR1-WQOeiTX6Tc-GNUZXCRGmMvPj-_-_ekXcwfzDxhW9qnnIumQ26wn3b_5kKILQLKSJsZJRS=s287-w287-h192-n-k-no-v1"
    ],
    "pricePerNight": 247.83,
    "pricePerNightText": "£248",
    "priceTotal": 495.66,
    "currency": "GBP",
    "checkIn": "2026-10-20",
    "checkOut": "2026-10-22",
    "adults": 3,
    "googleMapsFeatureId": "0x47e66ea52218c2af:0xa9f295c40a2bef54",
    "address": "31 Avenue Jules Rimet St Denis, 93210 Saint-Denis, France",
    "phone": "+33 1 49 46 54 54",
    "offers": [
        {
            "provider": "Priceline",
            "pricePerNight": 247.83,
            "priceTotal": 495.66,
            "bookingUrl": "https://www.priceline.com/r/?channel=meta&product=hotel&hotelid=3540105&checkin=20261020&checkout=20261022&rooms=1&cur=GBP&adults=3"
        }
    ],
    "cheapestProvider": "Priceline",
    "scrapedAt": "2026-09-29T20:06:02.820Z"
}
```

The **Output** tab shows an overview table with the most useful columns: name, nightly and total price, currency, cheapest site, rating, reviews, star class, address, dates and the Google Hotels link. The full records, including all offers and photos, are available through the "All fields" view and the API.

### How much does it cost to scrape Google Hotels?

The Actor uses pay-per-event pricing, so you pay for the results you get rather than for server time:

You are charged per result: once for each hotel record saved to the dataset. If you turn on `includeOffers`, there is an additional charge for each hotel whose hotel page returned address, phone or booking-site offers. It is off by default.

The exact charges are listed on the **Pricing** tab of the Actor page. Apify's free plan includes monthly platform credit, which is enough to try the Actor on a few hundred hotels.

To keep costs predictable, set `maxItems` to the number of hotels you actually need. A run never returns more than `maxItems` hotels per search phrase.

### Use with the API

You can run the Actor and read its results from your own code through the Apify API. Set your Apify API token (Console, Settings, API & Integrations) in the `APIFY_TOKEN` environment variable.

Python:

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("axiomworks/google-hotels-prices-scraper").call(run_input={
    "queries": ["hotels in Paris"],
    "maxItems": 20,
    "checkIn": "2026-11-12",
    "checkOut": "2026-11-14",
    "adults": 2,
    "currency": "USD",
})
for hotel in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(hotel["name"], hotel["pricePerNight"], hotel["cheapestProvider"])
```

JavaScript:

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('axiomworks/google-hotels-prices-scraper').call({
    queries: ['hotels in Paris'],
    maxItems: 20,
    checkIn: '2026-11-12',
    checkOut: '2026-11-14',
    adults: 2,
    currency: 'USD',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const lines = items.map((h) => `${h.name}: ${h.pricePerNight} ${h.currency}`);
process.stdout.write(lines.join("\n"));
```

cURL (starts a run and returns the dataset items when it finishes):

```bash
curl -X POST "https://api.apify.com/v2/acts/axiomworks~google-hotels-prices-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"queries": ["hotels in Paris"], "maxItems": 10, "currency": "USD"}'
```

The Actor also works with the Apify integrations for Make, Zapier, n8n, Google Sheets, Slack and webhooks, so you can send new results to a spreadsheet or trigger an alert when a price drops.

### Use with AI agents (MCP)

You can connect this Actor to AI assistants that support the Model Context Protocol (MCP), such as Claude Desktop, Cursor or VS Code, through the Apify MCP server. The agent can then search Google Hotels prices on its own when you ask it a travel question.

Add this to your MCP client configuration:

```json
{
    "mcpServers": {
        "apify": {
            "url": "https://mcp.apify.com?tools=axiomworks/google-hotels-prices-scraper"
        }
    }
}
```

The first time you connect, you will be asked to sign in to Apify, or you can pass your Apify API token as a Bearer token in the `Authorization` header.

Example prompts:

- "Find the 10 cheapest 4-star hotels in Barcelona for 3 to 5 December for 2 adults, in EUR, and tell me which booking site is cheapest for each."
- "Compare the price of the Novotel Suites Paris Stade de France across booking sites for 20 to 22 October."
- "List hotels near Times Square rated 4.5 or higher with their phone numbers and nightly prices for next weekend."
- "Which booking site is most often the cheapest for hotels in Rome in mid-November?"

### FAQ

**Why are some prices `null`?**
Google shows no price when a hotel is sold out for your dates, when it has not published rates yet, or when no booking site covers it. The hotel is still returned so you can see it exists, but `pricePerNight`, `priceTotal` and `cheapestProvider` are `null`.

**Why do my prices differ slightly from what I see in my browser?**
Google adjusts prices and the list of booking sites by the visitor's country, device and sign-in state. The Actor uses a residential proxy, and the booking sites it sees may differ a little from yours. The currency you choose is always respected.

**Are prices per night or for the whole stay?**
Both. `pricePerNight` is the nightly price and `priceTotal` is the price for the whole stay. With `includeOffers` on, both come from the cheapest offer, and each offer has its own per-night and total price. Whether taxes are included follows Google's display for the exit country.

**How many hotels can I get per search?**
Up to 1,000 per search phrase (the `maxItems` limit), as long as Google has that many for the area. Google shows about 20 hotels per results page, and the Actor follows the pages for you and removes duplicates.

**Can I add children?**
Not yet. The current version prices stays for adults only.

**Does the Actor need my Google account?**
No. It only reads public Google Hotels pages and never logs in.

**What happens if Google blocks a request?**
The Actor waits, switches to a new proxy session and retries. If a whole search fails after several attempts, the run ends with an error that says which search failed, instead of silently returning nothing.

### Is it legal to scrape Google Hotels?

The Actor only collects publicly available information about businesses: hotel names, prices, addresses, public phone numbers and ratings. It does not collect personal data about individuals and does not access anything behind a login.

Scraping public data is generally lawful in many countries, but the rules depend on where you are and how you use the data. Google's terms of service restrict automated access to its services, and Google's robots.txt disallows crawling of its travel search pages. You are responsible for making sure your use of the data complies with the laws that apply to you and with any agreements you have accepted. If you are unsure, ask a lawyer. Do not use the data to mislead customers, and respect the trademarks of Google and the booking sites.

### Feedback

Found a bug, missing field or a page that does not parse? Open an issue on the Actor's **Issues** tab in Apify Console and include the run ID and your input. We read every report and use it to improve the Actor.

# Actor input Schema

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

Hotel search phrases to run on Google Hotels, one per entry, e.g. 'hotels in Paris' or 'hotels near Times Square'. Provide this or hotelUrls.

## `hotelUrls` (type: `array`):

Google Hotels hotel page URLs to price directly, e.g. 'https://www.google.com/travel/hotels/entity/ChkI...'. Provide this or queries.

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

Maximum number of hotels to return for each search query, an integer from 1 to 1000, e.g. 50. Defaults to 50.

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

Check-in date in YYYY-MM-DD format, e.g. '2026-11-10'. Leave empty to use the date 7 days from today.

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

Check-out date in YYYY-MM-DD format, 1-30 nights after check-in, e.g. '2026-11-12'. Leave empty for one night.

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

Number of adult guests, an integer from 1 to 12, e.g. 2.

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

Three-letter uppercase ISO 4217 currency code for all prices, e.g. 'USD', 'EUR' or 'GBP'. Defaults to USD.

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

Google interface language code for names and texts, e.g. 'en' or 'en-GB'. Defaults to en.

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

Bill the hotel-offers event for hotels whose page details (address, phone, per-site offers with booking links, cheapest site) were added. Every hotel page is always opened so these fields are filled; set false to avoid the extra per-hotel event.

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

Apify Proxy settings for Google requests, e.g. the RESIDENTIAL group. Leave empty to try datacenter proxies first and fall back to residential automatically.

## Actor input object example

```json
{
  "queries": [
    "hotels in Paris"
  ],
  "maxItems": 20,
  "adults": 2,
  "currency": "USD",
  "language": "en",
  "includeOffers": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing hotel records.

# 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"
    ],
    "maxItems": 20,
    "adults": 2,
    "currency": "USD",
    "language": "en",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axiomworks/google-hotels-prices-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"],
    "maxItems": 20,
    "adults": 2,
    "currency": "USD",
    "language": "en",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("axiomworks/google-hotels-prices-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"
  ],
  "maxItems": 20,
  "adults": 2,
  "currency": "USD",
  "language": "en",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call axiomworks/google-hotels-prices-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,axiomworks/google-hotels-prices-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/Hk5Z7pXn1cxOxicEv/builds/LbPP6zqmest1UU2Tu/openapi.json
