# Google Hotels Scraper: Prices, Rates, Phone & Email by City/ZIP (`scrapebench/google-hotels-scraper`) Actor

Every hotel Google Hotels lists in a city, ZIP code, county or near a landmark, priced for your dates: stars, rating, phone, street address, website and the hotel's own email. Booking-site rates on request.

- **URL**: https://apify.com/scrapebench/google-hotels-scraper.md
- **Developed by:** [ScrapeBench](https://apify.com/scrapebench) (community)
- **Categories:** Travel, Lead generation
- **Security:** Limited permissions
- **Stats:** 2 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.003 / hotel

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, Rates, Phone & Email by City/ZIP

### Pain points

- Google's hotel list shows a phone number for only the first page of hotels; after that you open every hotel one by one.
- A saved run with a fixed check-in date starts failing the day that date passes.
- Google mixes vacation rentals into a hotel search from the second page on, so a list of hotels fills up with houses and apartments.
- Copying hotels, prices and phone numbers out of Google into a spreadsheet takes hours for one city.

### What we solve

- One input for the whole job: places (city, ZIP code, county, region, landmark or hotel name) and a stay. Several places in one run, each hotel returned once.
- Phone and street address for every hotel, read from each hotel's own Google page, not just the first page of results.
- Hotels, motels and inns only by default, vacation rentals only, or both: every row says which it is.
- The hotel's own email from its website (on by default, can be switched off), charged only when an email is found.

### Summary

Type the places you care about (a city, a ZIP code, a county, a region like Lake Tahoe, "near Moscone Center", or a hotel's name) and your stay, and get every hotel Google Hotels lists there: one row per hotel with its name, star class, Google rating and how the reviews split by star, the lowest price per night for your dates in US dollars, Google's own deal note ("20% less than usual"), phone number, street address, website, check-in and check-out times, the nearest airport and the drive there, coordinates and a Google Hotels link. Google's list carries a phone for only the first page of hotels, so the actor reads each hotel's own Google page for its phone and address. By default it also visits each hotel's website and returns the email published there; chain brand sites, which publish no property inbox, are skipped. Switch on booking-site rates to get every site's price for the stay (Booking.com, Expedia, Trip.com, the hotel's own site and others) with links. A check-in date in the past moves to tomorrow instead of failing the run.

### Who it's for

- Event, conference and group-travel planners sourcing room blocks near a venue
- Hotel revenue managers and owners watching a competitive set's prices
- Travel agencies and tour operators comparing hotels and rates for a trip
- Sales teams selling to hotels (software, linen, staffing, supplies) building a territory list
- Hospitality analysts and investors sizing hotel supply and prices in a market

### How to use

Set the input, run the actor, and collect results from the run's dataset (export to JSON/CSV/Excel, or pull via the Apify API). Example input:

```json
{
  "queries": [
    "San Francisco, CA"
  ],
  "checkIn": "2026-11-20",
  "checkOut": "2026-11-22",
  "maxResults": 20
}
```

See **Inputs** below for every available field.

### What you get

One row per record:

| Field | Description |
|---|---|
| `name` | The property's name on Google Hotels |
| `property_type` | hotel (hotels, motels, inns, resorts) or vacation_rental |
| `hotel_class` | Star class, 1 to 5 (null for unrated properties) |
| `rating` | Google guest rating, 1 to 5 |
| `review_count` | Number of Google reviews |
| `rating_breakdown` | Reviews per star, 5 to 1 |
| `price_per_night` | Lowest price per night Google shows for the stay, in USD |
| `currency` | Currency of the prices (USD) |
| `check_in` | Check-in day the price is for |
| `check_out` | Check-out day the price is for |
| `deal` | Google's own price note, such as "20% less than usual" |
| `phone` | The hotel's phone number |
| `address` | Street address |
| `website` | The hotel's own website |
| `email` | The hotel's email from its own website (null when none was found or the lookup is off) |
| `emails` | Every address of the hotel's own found on its website |
| `latitude` | Latitude |
| `longitude` | Longitude |
| `check_in_time` | The hotel's check-in time |
| `check_out_time` | The hotel's check-out time |
| `nearest_airport` | The airport Google lists near the hotel |
| `airport_drive_minutes` | Driving time to that airport, in minutes |
| `booking_rates` | With booking-site rates on: each site's price per night and total, before and after taxes, with a link |
| `entity_id` | Google's own ID for the property, unique per row |
| `google_hotel_url` | Opens the property on Google Hotels |
| `query` | The place this row was found for |
| `source_url` | Where the row came from (its Google Hotels page) |

Sample:

```json
{
  "name": "Hotel Griffon",
  "property_type": "hotel",
  "hotel_class": 3,
  "rating": 4.2,
  "review_count": 911,
  "rating_breakdown": {
    "5": 512,
    "4": 228,
    "3": 98,
    "2": 23,
    "1": 50
  },
  "price_per_night": 86.82,
  "currency": "USD",
  "check_in": "2026-11-20",
  "check_out": "2026-11-22",
  "deal": "20% less than usual",
  "phone": "(415) 495-2100",
  "address": "155 Steuart St, San Francisco, CA 94105",
  "website": "http://www.hotelgriffon.com/",
  "email": null,
  "emails": [],
  "latitude": 37.7927002,
  "longitude": -122.3923344,
  "check_in_time": "3:00 PM",
  "check_out_time": "11:00 AM",
  "nearest_airport": "San Francisco International Airport",
  "airport_drive_minutes": 25,
  "booking_rates": [],
  "entity_id": "ChgI5NCc0fWC5K2LARoLL2cvMXZ2MnNnZzYQAQ",
  "google_hotel_url": "https://www.google.com/travel/hotels/entity/ChgI5NCc0fWC5K2LARoLL2cvMXZ2MnNnZzYQAQ",
  "query": "San Francisco, CA",
  "source_url": "https://www.google.com/travel/hotels/entity/ChgI5NCc0fWC5K2LARoLL2cvMXZ2MnNnZzYQAQ"
}
```

### Inputs

| Field | Required | Type | Default | Description |
|---|---|---|---|---|
| `queries` | no | array | `["San Francisco, CA"]` | Where to look, one per line: a city (San Francisco, CA), a ZIP code (89501), a county (Washoe County, NV), a region (Lake Tahoe), a landmark (near Moscone Center) or a hotel's name. Each place is searched on its own and a hotel found twice is returned and charged once. |
| `query` | no | string | — | One place, for saved tasks and API calls that send a single value. Use Places above for several. |
| `checkIn` | no | string | — | YYYY-MM-DD. Prices are for this stay. Empty means 14 days from today. A date in the past moves to tomorrow (same number of nights) instead of failing the run, and a free row says so. |
| `checkOut` | no | string | — | YYYY-MM-DD. Empty means check-in plus the number of nights below. |
| `nights` | no | integer | `1` | Length of the stay when no check-out date is given (up to 30). |
| `propertyType` | no | string | `"hotels"` | Google mixes hotels and vacation rentals in its results. Hotels includes motels, inns and resorts. |
| `maxResults` | no | integer | `20` | Cap for EACH place. Google lists up to a few hundred per city; a whole state stops around 600, so split a state into counties or cities. |
| `includeDetails` | no | boolean | `true` | On by default: reads each hotel's own Google page for its street address and phone. Google's search list carries a phone only for the first ~18 hotels. No extra charge; turn off for a faster run with prices only. |
| `includeEmails` | no | boolean | `true` | On by default: visits each hotel's own website and returns the email published there. Charged separately, only for hotels where one is found. Chain brand sites (Marriott, Hilton, Hyatt...) publish no property email and are skipped. |
| `includeOffers` | no | boolean | `false` | Off by default: adds every booking site's price for the stay (Booking.com, Expedia, Hotels.com, the hotel's own site...) with a link, from each hotel's Google page. Charged per hotel that has rates. |
| `proxyConfiguration` | no | object | `{"useApifyProxy": false}` | Off by default, which is how this actor was tested. If a run comes back with a 'blocked' row, turn on a proxy (residential works). Included in the price. |

### Pricing (Pay Per Event)

You pay per result (`hotel`) — **no charge for empty runs**. Example: **1000 hotels** at *$0.003/result* ≈ **$3.00**.

Two lookups are charged separately. The email lookup is on by default: $0.002 per hotel where an email is found on its website (event "Email found"); no email found, nothing extra. Booking-site rates are off by default: $0.001 per hotel whose rates are returned (event "Hotel rates"). Phone and street address cost nothing extra. Compute and proxy are included; you pay only these events.

### Use cases

- Conference outreach: every hotel near the venue, with phone, address and email, to offer a group rate or list in the attendee guide.
- Rate shopping: the same set of hotels priced for the same nights, with each booking site's rate side by side.
- Trip sourcing: the cheapest 4-star hotels near an airport or landmark for given dates, with Google's deal notes.
- Territory lists: every hotel in the counties a sales rep covers, with phone and email, ready for a CRM.

### Why this actor

- Phone and street address for every hotel, not only the first page Google shows.
- A past check-in date rolls forward with a note instead of failing a saved run.
- Hotels and vacation rentals told apart on every row, filtered the way you ask.

### Limitations & updates

Prices are what Google Hotels shows for the stay at the time of the run, in US dollars, for two adults; they change by the hour, and a hotel Google has no rate for on those dates comes back without a price (173 of 419 in San Francisco for 20 to 22 November 2026). One search lists up to a few hundred properties: a city comes back whole, but a whole state stops at about 600, so search a state county by county or city by city. Vacation rentals are Google's listings of houses and apartments and have no phone or address. The email lookup reads only the hotel's own public website (up to 4 pages), does not guess or verify addresses, and skips chain brand sites. Booking-site links are the booking sites' own links as Google gives them and can expire.

### FAQ

**What can I search for?**

Anything Google Hotels understands as a place: a city ("San Francisco, CA"), a ZIP code ("89501"), a county ("Washoe County, NV"), a region ("Lake Tahoe"), a landmark ("near Moscone Center") or a hotel's name. Put several in Places; each is searched on its own and a hotel found by two of them is returned and charged once. Latitude and longitude are not accepted: Google answers them with the whole country.

**Which dates are the prices for?**

The check-in and check-out you give (or check-in plus a number of nights). Every row carries the check_in and check_out its price is for, as Google reported it. Leave check-in empty for a stay 14 days from today. A check-in in the past moves to tomorrow, same number of nights, and a free row says so, so a saved task keeps working.

**Where do the phone and address come from?**

Google's hotel list shows a phone for only its first page of hotels and no street address, so the actor opens each hotel's own Google Hotels page and reads both from there ("Phone and address for every hotel", on by default, no extra charge). Vacation rentals have no business phone and are not opened.

**How does the email lookup work?**

Unless you switch it off, the actor reads up to 4 pages of each hotel's own website (homepage plus contact pages) and returns the emails published there; booking-platform addresses are dropped. Chain brand sites (Marriott, Hilton, Hyatt, IHG, Wyndham, Choice, Best Western and others) publish no address for a single property and are skipped, so independent hotels are where emails come from. Measured in San Francisco on 2026-10-31: 7 of the first 18 hotels had an email on their website, all of them independents; none of the 6 chain sites did.

**What are booking-site rates?**

Switch on "Booking-site rates" and each hotel's row gets every site Google shows for your stay (Booking.com, Expedia, Trip.com, the hotel's own site and others), each with its price per night and total, before and after taxes, and a link to that site. Nob Hill Hotel in San Francisco had 20 sites for 20 to 22 November 2026.

**How many hotels come back, and how long does it take?**

Measured on 2026-10-31, run outside Apify through one proxy: San Francisco, priced for 20 to 22 November 2026, returned 419 hotels in about 5.5 minutes (searching about 1 minute, each hotel's page about 1.5 minutes, the email lookup about 2.5 minutes). Of the 419: 419 with a street address, 389 with a phone, 408 with a rating, 317 with a website, 246 with a price for those nights (Google had no rate for the rest on those dates) and 60 with an email found on their website. Google refused nothing. A first run of 20 hotels takes well under a minute.

**How am I charged?**

$0.003 per hotel returned. With the email lookup on (the default), $0.002 more per hotel where an email was found. With booking-site rates on, $0.001 more per hotel that has rates. Phone and address are included. Free rows (a refused search, a past date moved forward, input to fix) are never charged. Set "Maximum properties per place" to cap a run.

**What if Google refuses a search?**

The page is retried once after a pause. If Google still refuses, the hotels found so far are delivered and a free row says which place to run again; a refusal never reads as "no hotels here". Turning on a proxy (residential works) is the fix if it keeps happening.

### Which actor to choose

Works with:

- **Business Email, Phone & Contact Details Scraper** — You already have a list of hotel websites and want emails, phones and social links for each.

### Guides & use cases

Written up on **[scrapebench.dev](https://scrapebench.dev)** — the bench that runs and verifies this actor against the live source every night:

- **How-to:** [How to run Google Hotels Scraper: Prices, Rates, Phone & Email by City/ZIP](https://scrapebench.dev/guides/how-to-google-hotels-scraper/)
- **Use case:** [Every hotel in San Francisco with phone, address and email](https://scrapebench.dev/use-cases/san-francisco-hotels-contacts/)

More actors, coverage and nightly verification results: **[scrapebench.dev](https://scrapebench.dev)**

### Works with AI assistants (MCP)

Callable as an MCP tool, so Claude, Cursor, VS Code Copilot and other MCP clients can run it directly. Grab the config from the [MCP tab](https://apify.com/scrapebench/google-hotels-scraper/api/mcp) on this page — Apify hosts the server and keeps that snippet current, and OAuth signs you in on first connect, so no API token goes in your config file.

Then just ask:

> "Find every hotel in San Francisco for 20 to 22 November 2026 with its price per night, phone number, address and email."

Start with a small cap (20 hotels) to see the rows, then raise "Maximum properties per place" for the whole city. Runs started this way bill exactly like any other run.

### Data & lawful use

This actor collects publicly available information that Google (Google Hotels) and the hotels' own websites publishes for public
lookup — licence records, business listings and the contact details professionals list there.
Some of it identifies individuals (sole proprietors, licence holders, agents), so treat any
names, phone numbers and emails in your results as personal data.

When you run this actor, you decide what is collected and what it is used for, so you are the
controller of that data and we act only as your processor (Apify Standard Actor Contract).
You need a lawful basis for your use, must honour opt-out and deletion requests, and must
follow the marketing rules that apply to you (CAN-SPAM, TCPA, GDPR, CCPA and similar).
Don't use the output for unsolicited bulk messaging, for screening covered by the FCRA, or
for anything the source's own terms forbid.

Your results are stored in your own Apify account. We don't keep a copy of your results and
don't sell or share them.

### Disclaimer

This is an independent tool. It is not affiliated with, endorsed by or sponsored by
Google (Google Hotels) and the hotels' own websites. Names and marks are used only to describe the data source. Records are
provided as published by the source and may be out of date or incomplete. For anything
consequential (hiring, a permit, a legal decision), confirm the record with the issuing
agency. You are responsible for making sure your use complies with applicable law and the
source's terms.

### Need help?

Open an issue on this actor's **Issues** tab and we'll respond there. Bug reports, missing
fields and feature requests are all welcome. Guides and examples: [scrapebench.dev](https://scrapebench.dev).

If you are a person named in this data and want your record removed from our copy, email
apify-help@scrapebench.dev; the source agency remains the official record.

Your run may be used to improve our services. If something looks off, or you want this actor to fit your use better, please share your run data with us: [Apify Console → Settings → Security → Share run data with developers](https://console.apify.com/settings/security). It lets us see exactly what went wrong and keep improving the actor.

# Actor input Schema

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

Where to look, one per line: a city (San Francisco, CA), a ZIP code (89501), a county (Washoe County, NV), a region (Lake Tahoe), a landmark (near Moscone Center) or a hotel's name. Each place is searched on its own and a hotel found twice is returned and charged once.

## `query` (type: `string`):

One place, for saved tasks and API calls that send a single value. Use Places above for several.

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

YYYY-MM-DD. Prices are for this stay. Empty means 14 days from today. A date in the past moves to tomorrow (same number of nights) instead of failing the run, and a free row says so.

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

YYYY-MM-DD. Empty means check-in plus the number of nights below.

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

Length of the stay when no check-out date is given (up to 30).

## `propertyType` (type: `string`):

Google mixes hotels and vacation rentals in its results. Hotels includes motels, inns and resorts.

## `maxResults` (type: `integer`):

Cap for EACH place. Google lists up to a few hundred per city; a whole state stops around 600, so split a state into counties or cities.

## `includeDetails` (type: `boolean`):

On by default: reads each hotel's own Google page for its street address and phone. Google's search list carries a phone only for the first ~18 hotels. No extra charge; turn off for a faster run with prices only.

## `includeEmails` (type: `boolean`):

On by default: visits each hotel's own website and returns the email published there. Charged separately, only for hotels where one is found. Chain brand sites (Marriott, Hilton, Hyatt...) publish no property email and are skipped.

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

Off by default: adds every booking site's price for the stay (Booking.com, Expedia, Hotels.com, the hotel's own site...) with a link, from each hotel's Google page. Charged per hotel that has rates.

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

Off by default, which is how this actor was tested. If a run comes back with a 'blocked' row, turn on a proxy (residential works). Included in the price.

## Actor input object example

```json
{
  "queries": [
    "San Francisco, CA"
  ],
  "nights": 1,
  "propertyType": "hotels",
  "maxResults": 20,
  "includeDetails": true,
  "includeEmails": true,
  "includeOffers": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One row per property; free notice rows explain a refusal, a cut-off or input to fix.

# 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": [
        "San Francisco, CA"
    ],
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapebench/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": ["San Francisco, CA"],
    "maxResults": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapebench/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": [
    "San Francisco, CA"
  ],
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call scrapebench/google-hotels-scraper --silent --output-dataset

```

## MCP server setup

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