# Google Hotels Scraper - $3.50/1k, Live Prices (`dami_studio/google-hotels-scraper`) Actor

Scrape Google Hotels prices for your own dates. Google does not sell rooms. Booking sites feed it the rates, so each price matches your stay. Each row: hotel name, nightly price, stay total, rating, review count, class and photo. 10 searches a run, 100 hotels each. $3.50 per 1,000.

- **URL**: https://apify.com/dami\_studio/google-hotels-scraper.md
- **Developed by:** [Dami's Studio](https://apify.com/dami_studio) (community)
- **Categories:** Travel, Lead generation, Integrations
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.50 / 1,000 hotel results

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

Google does not sell hotel rooms. Hotels and booking sites feed their rates into Google for one specific itinerary, which is why a price on that page belongs to a set of dates rather than to the hotel.

The actor searches with the check-in and check-out you supply and returns one row per property: name, nightly price, stay total, currency, star rating, review count, hotel class, type, thumbnail and a link to the Google listing.

You search in plain phrases, the same ones you'd type into Google: "hotels in Lisbon", "family hotels near Disneyland Paris". Add check-in and check-out dates and the prices come back for your stay instead of Google's default one.

No login, no API key.

### What you get

```json
{
  "propertyToken": "ChcIhOzxxLOE6-8BGgsvZy8xdG0yYnl0ORAB",
  "searchQuery": "hotels in Lisbon",
  "name": "Independente Principe Real",
  "vendor": null,
  "price": 37,
  "priceText": "US$37",
  "currency": "USD",
  "totalPrice": 49,
  "totalPriceText": "US$49",
  "rating": 4.3,
  "reviewsCount": 1011,
  "hotelClass": 3,
  "hotelType": "hotel",
  "thumbnail": "https://lh3.googleusercontent.com/gps-cs-s/AHRPTWnxuzoBEzeQ...",
  "detailsUrl": "https://www.google.com/travel/hotels/entity/ChcIhOzxxLOE6-8BGgsvZy8xdG0yYnl0ORAB",
  "checkInDate": "2026-09-18",
  "checkOutDate": "2026-09-20",
  "scrapedAt": "2026-08-21T14:37:39.825Z"
}
```

Prices come as both a number and Google's own string. `price` is whatever the card labels per night, `totalPrice` is whatever it labels as the total. Don't expect one to be the other times the number of nights. The row above says $37 nightly and $49 total, and that isn't a parsing bug: Google prints those two figures from different rates, often from different booking sites, on the same card. Take each at face value and use `totalPrice` when what you care about is the cost of the stay.

`checkInDate` and `checkOutDate` are echoed onto every row, so a dataset built from several runs across different dates stays readable without you tracking which run was which.

`resolvedLocation` is the destination Google actually searched, taken from its own results heading. Ask for "hotels near the Eiffel Tower" and it reads `Paris`. It's worth glancing at, because it's the difference between the place you meant and a place Google settled on.

`propertyToken` is Google's stable id for the property. It's the field to key on if you're tracking the same hotel's price over time, since names get reformatted.

### Input

```json
{
  "searchQueries": ["hotels in Lisbon", "family hotels near Disneyland Paris"],
  "checkIn": "2026-09-18",
  "checkOut": "2026-09-20",
  "adults": 2,
  "currency": "EUR",
  "country": "fr",
  "language": "en",
  "maxItemsPerQuery": 50
}
```

- `searchQueries` — natural destination searches. Up to 10 per run.
- `checkIn` / `checkOut` — `YYYY-MM-DD`. Both optional, but supply them: without dates Google shows its own default stay, and the prices you get back are for that, not yours.
- `adults` — 1 to 12, default 2.
- `country` — two-letter Google edition code (`us`, `gb`, `fr`, `ca`). Default `ca`. This changes results and pricing more than people expect.
- `currency` — three-letter hint like `USD`, `EUR`. Google may ignore it and use the currency for the country edition, which is why every row carries `currency` explicitly.
- `language` — interface language, default `en`.
- `maxItemsPerQuery` — default 50, ceiling 100.

### Limits

- **A destination Google can't place gets you nothing, on purpose.** Google never answers "no such place". If it can't work out where you mean, it quietly serves hotels near whichever address the request came from and the page looks completely normal — real hotels, real prices, real ratings, in a city you never asked about. This actor checks the destination Google says it searched against the one you asked for, and when they don't match it returns a note explaining that instead of the rows. Nothing is delivered and nothing is charged. If a search comes back that way, it's usually a spelling slip or a place name that needs narrowing: "Springfield Illinois" rather than "Springfield".
- **10 searches per run, 100 hotels per search.** A broad city search won't return every hotel in the city. You get Google's own results list, deepened as far as the cap.
- **Prices are live and they move.** A price scraped this morning may not exist this afternoon. Anything price-tracking needs repeat runs, keyed on `propertyToken`.
- **`adults` is sometimes ignored.** Some public result layouts don't honour it. Google decides that, not the actor.
- **`vendor` is often null.** Google doesn't always name which booking site the rate came from on the results page.
- Dropping the dates makes prices non-comparable across runs. Always set them for anything serious.
- Rating and review count come from Google, not the hotel or a booking site, so they won't match a Booking.com figure.

### Proxy

The run goes direct first. If Google blocks it, rate-limits it, or hands back a page with no properties, `fallbackToProxy` retries through Apify Proxy. It's on by default. Turn it off to keep every request on the platform's own address.

Residential or SERP proxies may be needed for high-volume or geo-sensitive work, and those are metered. They cost extra on top of the per-hotel price below. Worth knowing before you scale a run up.

### Billing

$3.50 per 1,000 hotel listings.

Charged per hotel row delivered. A search that comes back empty costs nothing, and neither does one where Google couldn't place your destination. Your ceiling per run is 10 searches × 100 hotels × $0.0035, so $3.50 at the absolute maximum, before any proxy bandwidth you opt into.

# Actor input Schema

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

Destination searches such as 'hotels in Toronto' or 'family hotels near Disneyland Paris'. One row is returned per hotel and each row includes the query that produced it.

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

Optional check-in date in YYYY-MM-DD format. Google may show its default stay when dates are omitted or unavailable.

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

Optional check-out date in YYYY-MM-DD format. Must be after check-in when both dates are supplied.

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

Number of adults for the hotel search. Google may ignore this field for some public result layouts.

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

Google interface language, for example en, fr, or de.

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

Two-letter Google country edition code, such as ca, us, gb, or fr.

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

Optional three-letter currency hint such as CAD, USD, or EUR. Google may display the currency associated with the country edition.

## `maxItemsPerQuery` (type: `integer`):

Maximum number of unique hotel rows returned for each search query.

## `fallbackToProxy` (type: `boolean`):

If direct Google traffic is blocked, rate-limited, or comes back with no properties, retry the search through Apify Proxy. Turning this off keeps every request on the platform's own address.

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

Optional Apify Proxy settings used only when proxy fallback is enabled. Residential or SERP proxies may be required for high-volume or geo-sensitive traffic and incur extra cost.

## Actor input object example

```json
{
  "searchQueries": [
    "hotels in Barcelona"
  ],
  "checkIn": "",
  "checkOut": "",
  "adults": 2,
  "language": "en",
  "country": "ca",
  "currency": "",
  "maxItemsPerQuery": 50,
  "fallbackToProxy": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

One dataset row per public Google Hotels property. Empty, blocked, and invalid runs return one uncharged diagnostic or sample row.

# 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 Barcelona"
    ]
};

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

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

```

## MCP server setup

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