Google Hotels Fast Search Scraper
Pricing
from $25.00 / 1,000 hotel results
Google Hotels Fast Search Scraper
Collect structured Google Hotels price snapshots for city and hotel queries. Built for developers and data teams running monitoring jobs or building datasets, with requested-currency validation, booking URLs when available, and pay-per-result billing.
Pricing
from $25.00 / 1,000 hotel results
Rating
0.0
(0)
Developer
Juyeop Park
Maintained by CommunityActor stats
0
Bookmarked
29
Total users
4
Monthly active users
3 days ago
Last modified
Categories
Share
Google Hotels Fast Search
Hotel price snapshots for developers and data teams that need structured data for monitoring, analysis, or internal products.
Run city queries or specific hotel names, keep the requested market and currency in the output, and export each run to an Apify Dataset. Schedule the same input to build a history of observed prices over time.
Use this Actor to:
- capture a price snapshot for one or more cities;
- monitor a hotel watchlist on a daily or weekly schedule;
- build a dataset for pricing analysis or market research;
- send completed runs to a database, spreadsheet, or webhook workflow.
Pricing is Pay Per Event. The Actor charges
hotel-resultat $0.025 for each billable hotel row written to the dataset. Apify also charges the configuredapify-actor-startevent based on run memory. A query with no billable hotel result does not incur ahotel-resultcharge.
Results reflect what Google Hotels displayed for the selected dates, guests, country, and currency when the run executed. Provider coverage and booking links vary by hotel and query.
What the dataset contains
Each hotel is written as one structured row. Base fields include the query, hotel identity, ratings, observed summary price, requested currency, dates, and Google Hotels URL.
When detail scraping is enabled, the Actor can also collect:
- provider price rows with
provider,price,currency, andbookingUrlwhen Google exposes a booking link; - overview fields such as address, phone, highlights, and nearby places;
- reviews and third-party rating summaries;
- photo URLs;
- check-in details and amenities.
The Actor checks available currency, date, and market signals before retaining detailed provider prices. Rows with a detected context mismatch are dropped rather than mixed into the final prices array. This behavior was cloud-tested with Singapore inputs using country="sg", currency="SGD", and an explicit Residential proxy. It is evidence for that workflow, not a guarantee that every hotel will return the same number of providers.
Monitoring workflows
City price snapshots
Run queries such as hotels in Singapore Orchard Road or hotels in Tokyo Shinjuku. Store each completed dataset with its input dates and scrapedAt timestamp for later comparison.
Repeated hotel monitoring
Schedule a specific hotel query with the same country, currency, dates, and guest count. Compare datasets across runs in your own workflow to identify observed price changes. The Actor returns snapshots; it does not calculate historical diffs by itself.
Dataset building
Collect normalized hotel rows for a selected list of markets. Export JSON or CSV, or retrieve the dataset through the Apify API for loading into a warehouse, dashboard, or notebook.
Booking-link research
Use detail mode when your downstream process needs provider-level price rows. bookingUrl is included when it is present in the Google Hotels result. Availability and provider count vary by hotel.
Localized market checks
Set country and currency together, for example sg and SGD. The Actor keeps context-valid price rows in the requested currency and records detail status fields when enrichment is partial.
Key features
| Feature | Details |
|---|---|
| Structured price snapshots | One dataset row per hotel with query, dates, observed prices, currency, identity, and scrape timestamp |
| Provider-level detail | Price and booking-link rows when exposed by Google Hotels; provider coverage varies by hotel |
| Currency and market validation | Detailed prices are checked against available currency, date, and market signals |
| Monitoring-ready output | Stable dataset fields for scheduled runs, API retrieval, and downstream comparisons |
| Optional detail sections | Overview and Prices are always in the output shape; Reviews, Photos, and About can be requested |
| Supported markets | 22 country options and 22 currency options in the existing input contract |
| Filtering and sorting | Filter by rating or maximum observed price and sort the resulting dataset |
| Bounded fallback status | Detail runs report success or partial so pipelines can distinguish complete enrichment from a base-row fallback |
| Residential proxy support | Apify Residential traffic is aligned with the requested country when Apify Proxy is enabled |
| Existing scale limits | Up to 5 queries per run; search-only and detail modes retain their documented result limits |
How to Use
Step 1 - Set your search queries
Enter one or more natural-language queries in the Search Queries field. Examples:
hotels in New Yorkhotels in Tokyo Shibuyaluxury hotels Singapore Marina Baybudget hotels Paris near Eiffel Tower
You can run up to 5 queries per run, each returning up to 100 hotels.
Step 2 - Set your travel dates
Enter Check-in Date and Check-out Date in YYYY-MM-DD format. If left empty, the Actor defaults to tomorrow and the following day.
Step 3 - Configure guests and locale
Set Number of Adults (1-10), Country (affects which OTAs appear and local pricing), and Currency (the currency for all displayed prices).
Step 4 - Choose data sections
The Actor always keeps Overview and Prices in the output shape. By default, it runs in fast search-only mode (scrapeOtaPrices=false) and extracts basic price/overview signals from search results. Enable Scrape Hotel Detail Pages to visit each hotel page for richer OTA prices, reviews, photos, and about data; this mode takes longer, uses a minimum 300-second per-request timeout, and can push a partial base row with detailScrapeStatus="partial" if optional detail enrichment times out. Optionally add:
- Guest Reviews — individual guest reviews plus third-party aggregated ratings
- Hotel Photos — full photo gallery
- About / Amenities — check-in times, check-out times, and categorized amenities
More sections increase run time but provide richer data.
Step 5 - Apply filters and sorting
Use Minimum Rating (0-5) and Maximum Price Per Night to narrow results. Set both to 0 (default) to disable filtering. Choose a sort order for the output dataset.
Step 6 - Run and export
Click Save & Run. Results appear in the Dataset tab as structured JSON records. Export to JSON, CSV, Excel, or XML. Connect to downstream systems via the Apify API.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
queries | string[] | required | Hotel search queries (max 5). E.g., ["hotels in New York"] |
checkIn | string | tomorrow | Check-in date in YYYY-MM-DD format |
checkOut | string | day after tomorrow | Check-out date in YYYY-MM-DD format |
adults | integer | 2 | Number of adult guests (1-10) |
country | string | "us" | Country code for localized results (22 options) |
currency | string | "USD" | Currency code for displayed prices (22 options) |
maxResults | integer | 1 | Maximum hotels per query. Search-only supports 1-100; detail-page scraping is capped to 20 for reliability |
scrapeOtaPrices | boolean | false | Visit each hotel's detail page to collect OTA prices, reviews, photos, and about data. When enabled, runtime raises per-request timeout to at least 300 seconds and emits detail status fields for bounded fallback |
dataSections | string[] | ["overview", "prices"] | Data sections to collect: overview, prices, reviews, photos, about |
sortBy | string | "price_low" | Sort order: price_low, price_high, rating, reviews, name |
minRating | number | 0 | Minimum Google rating filter — set to 0 to disable |
maxPrice | integer | 0 | Maximum nightly price filter — set to 0 to disable |
proxy | object | Apify Residential | HTTP proxy configuration. Residential proxies strongly recommended for Google Hotels scraping |
requestHandlerTimeoutSecs | integer | 120 | Maximum seconds allowed per request (120-1800). Detail-page scraping is automatically raised to at least 300 seconds; increase further for slow proxies or larger runs |
Supported Countries
us, gb, sg, jp, kr, de, fr, au, ca, in, th, br, it, es, nl, ae, hk, tw, my, id, ph, vn
Supported Currencies
USD, EUR, GBP, JPY, KRW, SGD, AUD, CAD, INR, THB, BRL, TWD, MYR, IDR, PHP, VND, AED, HKD, CHF, SEK, NOK, DKK
Data Sections
| Value | Always Included | Description |
|---|---|---|
overview | Yes (cannot be removed) | Hotel description, address, phone number, highlights, and nearby places |
prices | Yes (cannot be removed) | Available provider prices, booking URLs when present, and cancellation details when exposed by Google Hotels |
reviews | No | Individual guest reviews, star rating breakdown, and third-party review site ratings |
photos | No | Hotel photo gallery URLs |
about | No | Full hotel description, check-in/out times, address, and amenities by category |
Output
Each hotel is saved as a single JSON object in the dataset. Optional fields are present only when the corresponding dataSections entry is selected.
Base Fields (always present)
| Field | Type | Description |
|---|---|---|
query | string | The search query that returned this hotel |
hotelName | string | Hotel name |
address | string | null | Hotel address or location description |
rating | number | null | Google rating score (e.g., 4.2) |
reviewCount | integer | null | Total number of reviews |
starRating | integer | null | Hotel star classification (2-5) |
lowestPrice | number | null | Lowest nightly price retained from the available result rows |
currency | string | Requested currency code for the hotel row |
prices | OtaPrice[] | Context-valid provider price rows available for this hotel |
amenities | string[] | Hotel amenities list |
imageUrl | string | null | Hotel thumbnail image URL |
latitude | number | null | Latitude coordinate (from API intercept) |
longitude | number | null | Longitude coordinate (from API intercept) |
checkIn | string | Check-in date in YYYY-MM-DD format |
checkOut | string | Check-out date in YYYY-MM-DD format |
adults | integer | Number of adult guests |
dealText | string | null | Special deal text (e.g., "25% less than usual") |
url | string | Google Hotels URL for this hotel |
scrapedAt | string | ISO 8601 timestamp of when data was scraped |
detailScrapeStatus | string | null | Detail-mode status: success when requested detail data was collected, partial when base search data was pushed after a bounded fallback |
detailScrapeStage | string | null | Detail stage that completed or triggered fallback, such as detail-hotel, api-fallback, or actor-deadline |
detailScrapeElapsedMs | integer | null | Detail stage elapsed time in milliseconds |
detailScrapeError | string | null | Fallback reason when detailScrapeStatus is partial; null on detail success |
OTA Price Object (prices[])
| Field | Type | Description |
|---|---|---|
provider | string | OTA provider name (e.g., "Booking.com") |
price | number | Nightly price from this provider |
currency | string | Currency code |
bookingUrl | string | Provider booking link when exposed by Google Hotels |
cancellation | string | null | Cancellation policy (e.g., "Free cancellation") |
features | string[] | Additional features (e.g., "Breakfast included") |
Optional Nested Objects
overview (when overview section selected)
| Field | Type | Description |
|---|---|---|
description | string | null | Hotel description and highlights summary |
address | string | null | Hotel address |
phone | string | null | Hotel phone number |
highlights | string[] | Key highlights and features |
nearbyPlaces | string[] | Nearby points of interest |
reviews (when reviews section selected)
| Field | Type | Description |
|---|---|---|
overallRating | number | null | Overall review score |
totalReviews | string | null | Total review count text |
ratingBreakdown | object | Star rating distribution (1-5 stars) |
reviews | ReviewItem[] | Individual guest reviews (text, rating, date, author) |
thirdPartyReviews | ThirdPartyReview[] | Aggregated ratings from Tripadvisor, Priceline, etc. |
photos (when photos section selected)
| Field | Type | Description |
|---|---|---|
photos | string[] | Array of hotel photo URLs |
about (when about section selected)
| Field | Type | Description |
|---|---|---|
description | string | null | Full hotel description |
checkInTime | string | null | Check-in time (e.g., "3:00 PM") |
checkOutTime | string | null | Check-out time (e.g., "12:00 PM") |
address | string | null | Hotel address |
amenitiesByCategory | object | Amenities organized by category name |
Sample Output
The record below illustrates the existing output shape for a "hotels in New York" query with all five data sections enabled. Values, provider coverage, photos, and booking links vary by query, hotel, dates, and market.
The Manhattan at Times Square Hotel
{"query": "hotels in New York","hotelName": "The Manhattan at Times Square Hotel","address": "790 7th Ave, New York, NY 10019","rating": 4.2,"reviewCount": 8547,"starRating": 4,"lowestPrice": 259,"currency": "USD","prices": [{"provider": "Vio.com","price": 259,"currency": "USD","bookingUrl": "https://...","cancellation": "Free cancellation","features": []},{"provider": "Booking.com","price": 271,"currency": "USD","bookingUrl": "https://...","cancellation": "Free cancellation","features": []},{"provider": "Hotels.com","price": 285,"currency": "USD","bookingUrl": "https://...","cancellation": "Free cancellation","features": []},{"provider": "eDreams","price": 377,"currency": "USD","bookingUrl": "https://...","cancellation": null,"features": []}],"amenities": ["Free Wi-Fi", "Parking ($)", "Air conditioning", "Pet-friendly", "Fitness center", "Restaurant"],"checkIn": "2026-03-06","checkOut": "2026-03-07","adults": 2,"dealText": null,"scrapedAt": "2026-03-05T09:15:22.000Z","overview": {"description": "Located in the heart of Midtown Manhattan, steps from Times Square...","address": "790 7th Ave, New York, NY 10019","phone": "+1 212-581-3300","highlights": ["Prime Times Square location", "Recently renovated rooms"],"nearbyPlaces": ["Times Square (0.1 mi)", "Central Park (1.2 mi)", "Empire State Building (0.8 mi)"]},"reviews": {"overallRating": 4.2,"totalReviews": "8,547","ratingBreakdown": { "5": 3200, "4": 2800, "3": 1500, "2": 700, "1": 347 },"reviews": [{"text": "Great location, clean rooms, friendly staff. Would stay again.","rating": 5,"date": "2025-07-15","author": "John D."}],"thirdPartyReviews": [{ "siteName": "Tripadvisor", "rating": "4.0", "reviewCount": "4,200" },{ "siteName": "Priceline", "rating": "8.2", "reviewCount": "1,100" },{ "siteName": "Trip.com", "rating": "4.1", "reviewCount": "980" },{ "siteName": "Hotels.com", "rating": "8.4", "reviewCount": "2,300" }]},"photos": {"photos": ["https://lh5.googleusercontent.com/p/AF1QipN...","https://lh5.googleusercontent.com/p/AF1QipN..."]},"about": {"checkInTime": "4:00 PM","checkOutTime": "12:00 PM","address": "790 7th Ave, New York, NY 10019","amenitiesByCategory": {"Connectivity": ["Free Wi-Fi", "Business center"],"Dining": ["Restaurant", "Bar/Lounge", "Room service"],"Fitness": ["Fitness center"],"Policies": ["Pet-friendly", "Parking ($)", "Air conditioning"]}}}
This example does not promise a fixed number of providers, reviews, or photos. Use a small run with your own market and dates to confirm coverage before scheduling a larger job.
Pricing
This Actor uses Pay Per Event (PPE) pricing.
| Event | Price | When it is charged |
|---|---|---|
hotel-result | $0.025 per event | Once for each billable hotel row written to the dataset |
apify-actor-start | $0.00005 per event | At run start; Apify determines the event count from the run memory configuration |
Diagnostic rows are not billed as hotel-result. A query that produces no billable hotel row has no hotel-result event, although the Actor start event still applies. In successful runs, chargedEventCounts.hotel-result should match the number of billable hotel rows.
Hotel-result cost examples
The estimates below show only the hotel-result component. The Actor start event is additional.
| Scenario | Billable hotel rows | Hotel-result charge |
|---|---|---|
| Single city snapshot | 20 | $0.50 |
| Three-city snapshot with 20 rows per city | 60 | $1.50 |
| Daily watchlist with 50 rows | 50 per run | $1.25 per run |
Start with maxResults: 1 to check coverage and output for your target market before increasing the result count.
Runtime notes
- Search-only mode (
scrapeOtaPrices: false) reads summary data without visiting each hotel detail page. - Detail mode visits hotel pages for provider prices and optional sections. It takes longer and can return a base row with
detailScrapeStatus="partial"when optional enrichment cannot finish within the bounded timeout. - Multiple queries are supported, but duration depends on result count, selected sections, proxy quality, and Google Hotels response time.
- Retry deduplication prevents an already collected hotel from being billed twice when a query is retried.
Operating tips
Use residential proxies The Actor defaults to Apify Residential proxies because Google Hotels may block datacenter traffic. Custom or datacenter proxies can produce empty results or navigation failures.
Start with a small test run
Set maxResults to 1 and keep dataSections at ["overview", "prices"] for your first run. Check the dataset, currency, and booking-link coverage before increasing the result count.
Enable only the sections your pipeline uses Each additional detail section can increase run time. Select only the fields your downstream pipeline uses.
Use specific, location-aware queries
More specific queries return more relevant results. "hotels in Tokyo Shibuya near station" is more precise than "hotels in Japan". Google Hotels returns city-level results — overly broad geographic queries may not return useful data.
Disable scrapeOtaPrices for fast metadata runs
When you only need hotel names, ratings, and summary prices from search results, set scrapeOtaPrices: false. This avoids the per-hotel detail-page step.
Schedule daily runs for price monitoring Use Apify Scheduling to run this Actor on a daily cadence with the same queries. Use the Apify API to compare datasets across runs and detect price changes over time.
Review timeout settings for detail runs
The Actor applies a dynamic minimum timeout in detail mode. Larger result sets, slow proxies, or extra sections may still require a higher requestHandlerTimeoutSecs value.
Limitations
- Maximum 5 queries per run — each query is a separate Google Hotels search
- Maximum 100 hotels per query — capped by Google Hotels' result set pagination
- Display prices only — prices reflect what Google Hotels shows at scrape time and do not include taxes, fees, or member-only discounts applied during checkout
- Dynamic DOM dependency — Google Hotels updates its frontend periodically; minor extraction issues may occur after major UI changes
- OTA coverage varies by hotel — smaller or boutique properties may have fewer OTA partnerships and fewer prices in the comparison table
- Residential proxy recommended — the Actor defaults to Apify Residential because datacenter traffic may be blocked or return empty pages
- Adults-only occupancy — currently supports adult guest count only; children and multi-room configurations are not supported
Integrations
Apify API
Trigger runs and retrieve results programmatically:
# Start a runcurl -X POST \"https://api.apify.com/v2/acts/YOUR_ACTOR_ID/runs?token=YOUR_API_TOKEN" \-H "Content-Type: application/json" \-d '{"queries": ["hotels in Singapore"],"checkIn": "2026-04-01","checkOut": "2026-04-02","maxResults": 20,"dataSections": ["overview", "prices", "reviews"]}'
# Retrieve results from the datasetcurl "https://api.apify.com/v2/datasets/DATASET_ID/items?token=YOUR_API_TOKEN&format=json"
Webhooks
Configure webhooks in the Actor settings to receive a POST notification when a run completes. Use the notification to load a dataset into a database or start your own comparison and alert workflow.
Scheduled Runs
Use Apify Scheduling to run the same input daily or weekly. Store the resulting dataset IDs so your own pipeline can compare observations across runs.
Data Export Formats
Results can be exported directly from the Dataset tab:
- JSON — full structured data, ideal for API consumers and data pipelines
- CSV — flat format for spreadsheet analysis (nested objects are serialized)
- Excel (.xlsx) — for manual review and reporting
- XML — for legacy system integration
Zapier and Make
Connect Actor runs to Zapier or Make (Integromat) workflows via the native Apify integration. Push hotel price data automatically to Google Sheets, Airtable, Slack, or any connected service.
FAQ
Does this Actor require a Google account or API key?
No. The Actor accesses Google Hotels as a standard browser session. No Google account, API key, or special credentials are required.
How accurate are the prices?
Prices reflect what Google Hotels displays at scrape time for the specified dates and guest count. They are display prices before taxes and fees. Actual checkout prices on OTA sites may differ due to taxes, service charges, or member-only discounts.
Can I search for a specific hotel by name?
Yes. Use a precise query such as "Marriott Marquis Times Square New York" to target a specific property. Note that Google may still return nearby alternatives. You can filter by hotelName in post-processing.
Why do some hotels have fewer OTA providers?
Smaller or boutique hotels may have fewer OTA partnerships. If a hotel has no price comparison data on Google Hotels, prices will be an empty array and lowestPrice will be null.
Can I run multiple queries to compare prices across different date ranges?
All queries in one run share the same checkIn and checkOut values. Run the Actor separately for each date range. hotel-result is charged per billable hotel row, not per query.
What happens if Google updates its UI?
The Actor combines API interception with DOM selectors. Changes to Google Hotels can affect either extraction path and may require an Actor update.
Why is scrapeOtaPrices disabled by default?
The default search-only path returns hotel identity, ratings, and summary price signals without visiting each hotel detail page. Enable scrapeOtaPrices when you need provider-level prices and booking URLs, and allow more run time for that work.
Can I use custom proxies instead of Apify Residential?
Yes. Set proxy.useApifyProxy: false and provide your proxy URLs in proxy.proxyUrls. Residential or mobile proxies are recommended; datacenter proxies may be blocked by Google Hotels.
Why is starRating null for some hotels?
Star rating is extracted from Google Hotels search results. Some hotels — particularly smaller or unclassified properties — do not have a star classification displayed by Google, resulting in a null value.