Google Maps Extractor with Reservation & Order Online Links
Pricing
from $2.99 / 1,000 results
Google Maps Extractor with Reservation & Order Online Links
Analyze local markets with fresh data from Google Maps. This actor helps you scrape key info on businesses in any region—great for research, expansion planning, or mapping competitors by category and location.
Pricing
from $2.99 / 1,000 results
Rating
0.0
(0)
Developer
SimpleAPI
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
6 days ago
Last modified
Categories
Share
Google Maps Scraper — Places, Reservation Links & Contact Data
Google Maps Extractor With Reservation & Order Online Links scrapes Google Maps business listings and, for every listing in the same request, the online-booking action Google carries in the same payload: the reservation or appointment deep link, the platform domain behind it (OpenTable, Resy, SevenRooms, TheFork, Tripleseat, Vagaro, and others Google surfaces), Google's own Reserve URL, and the button text shown on the listing. Each row also carries the standard place fields — name, full_address, phone, website, avg_rating, place_id, coordinates and today's opening hours. It's built for restaurant-tech and booking-platform vendors, local lead-gen agencies, and market researchers who need to know not just where a business is, but how someone books it.
🧭 What is google-maps-extractor-with-reservation-order-online-links?
It's a Google Maps scraper that reads the same map-search payload your browser gets when you search Google Maps, decodes the place record, and — in this build — also decodes the booking-action block Google ships alongside it. No Google account, API key, or Places API billing is required. Search is driven by keyword and location pairs (e.g. "restaurants" in "New York") or by pasting Google Maps links directly; results are deduplicated across every search by Google's own place_id.
Key capabilities, from the source:
- 🔎 Discovery by keyword × location, or by URL. Every
keywordsentry is searched in everylocationsentry;urls(Google Maps/maps/search/or/maps/place/links) are worked in addition, not instead. - 📇 Core identifying and contact fields on every row — name, full address, phone, website, coordinates, Google's stable
place_id. - 🍽️ The booking action as structured data, not a screenshot — channel classification (
third_party/direct_site/google_reserve/none), provider domain and display name, the deep link itself, and Google's own Reserve URL — extracted from the same response, with no extra HTTP request per place. - 🎯 A bookable-only / no-booking filter (
bookingPresence) and a provider allow-list (bookingProviders), so the output is already segmented into the list you actually sell against. - 📍 Area-accurate results — a bounding-box check (
restrictToRequestedArea) discards places outside the geocoded area instead of letting Google's radiating search leak neighbouring regions into your data. - 📦 Exports to JSON, CSV, Excel, or via the Apify API through the standard Apify dataset — no separate export step.
📊 What data can I extract with google-maps-extractor-with-reservation-order-online-links?
Every row combines the base place record with the booking columns this build adds and two run-context fields. Field names below are the exact JSON keys src/main.py and src/booking.py write to each row.
| Field | Example value | Use case |
|---|---|---|
rowType | "place" | Row-type discriminator (this build only emits "place" rows) |
name | "Katz's Delicatessen" | Business name |
full_address | "205 E Houston St, New York, NY 10002" | Google's own one-line formatted address |
street_address | "205 E Houston St" | Address component |
city | "New York" | Address component |
state | "New York" | Address component |
zip | "10002" | Address component |
country_code | "US" | Address component |
phone | "(212) 254-2246" | Contact / cold-outreach field |
website | "https://www.katzsdelicatessen.com/" | Contact field; also used to decide whether a booking link is the venue's own site |
avg_rating | 4.5 | Google's average rating |
tags | ["Deli"] | Google's own category tags |
place_id | "ChIJCar0f49ZwokR6ozLV-dHNTE" | Google's stable place identifier; used to dedupe across the whole run |
lat / long | 40.7223 / -73.9874 | Coordinates |
hours | [{"day":"Sunday","hours":"8 AM-10:45 PM","opens_at":"08:00","closes_at":"22:45"}] | Opening hours — current day only, see the limitation below |
has_booking_action | true | Filled on every row; the field to test before reading any other booking column |
booking_channel | "third_party" | third_party | direct_site | google_reserve | none |
booking_provider_count | 1 | Count of distinct third-party platforms detected (0 when none) |
booking_providers | ["opentable.com"] | Third-party platform domains only |
booking_provider_names | ["OpenTable"] | Google's display names for those platforms |
booking_domains | ["opentable.com"] | Every domain seen in the booking block, including the venue's own site if it hosts booking |
booking_urls | ["https://www.opentable.com/r/katzs-delicatessen"] | The booking/reservation deep links themselves |
google_reserve_url | "https://www.google.com/maps/reserve/v/dine/c/..." | Google's own Reserve link, with per-request echo parameters stripped |
booking_action_labels | ["Reserve a table"] | The CTA button text Google shows on the listing |
provider_logo_urls | ["https://lh3.googleusercontent.com/...=w80-h80"] | Platform logo images, resized to 80×80 — only present when includeProviderLogos is true |
search_term | "restaurants" | The keyword that produced this row |
search_area | "New York" | The location (or URL) that produced this row |
🎟️ Booking-platform signals
booking_channel is the field to filter and segment on. It is derived, in order: any domain that isn't the venue's own site and isn't Google itself → third_party; otherwise a booking link that resolves to the venue's own website → direct_site; otherwise a Google Reserve link with no named platform behind it → google_reserve; otherwise none. A restaurant-tech vendor building a switch-target list filters on booking_channel == "third_party" and reads booking_providers for the platform name; a booking aggregator prospecting for new venues filters on has_booking_action == false.
📍 Location and area-targeting fields
lat/long, city, state, country_code and place_id are what you group, map, or dedupe on. search_term and search_area record which keyword/location (or which pasted URL) produced each row, so a multi-city, multi-keyword run can still be sliced back apart after the fact.
⚙️ How does google-maps-extractor-with-reservation-order-online-links differ from the official Google Places API?
Google's own Places API (New) can return place details, but the reservation data this Actor is built around isn't in it: Place.reservable is a plain boolean — it tells you a venue supports reservations, with no link, no provider name, and no way to tell OpenTable from a venue's own booking widget (Google Places API Place reference, checked 2026-08-04). This Actor reads the same map-search response your browser gets and pulls the actual deep link, the provider domain, and the CTA text out of it.
| Feature | Google Places API (New) | This Actor |
|---|---|---|
| Booking/reservation data | reservable boolean only — no URL, no provider | Deep link, provider domain + display name, Google Reserve URL, CTA label |
| Setup | Google Cloud project, API key, billing account enabled | Apify account only — no Google credentials |
| Billing model | Per-field SKU tiers (Essentials / Pro / Enterprise / Enterprise + Atmosphere); reviews and reservable sit in the Enterprise + Atmosphere tier | Apify pay-per-event (row_result) |
| Opening hours | Full 7-day schedule (regularOpeningHours.periods) | Current day only (see below) |
| Bulk multi-city sweep | One place per request, billed per request | One run sweeps every keyword × location pair, deduplicated on place_id |
| Area-leak protection | Not applicable — a Place Details call always returns the place you asked for | Bounding-box filter plus a pre-run connection check |
Why doesn't the official API expose the booking platform?
Google's Places API is built around structured place metadata, and reservable is deliberately a capability flag, not a link — Google's own field reference documents it as "Specifies if the place supports reservations," with no companion field for the provider or the URL (checked 2026-08-04). The reservation deep link, the provider's domain, and the Reserve button text only exist in the Maps front-end's own search response, which is the surface this Actor reads. If your workflow only needs to know whether a place takes reservations, the Places API's reservable field is enough. If you need to know who runs that booking — the actual platform and link — that data isn't in the official API's Place resource at all, and this is what this build extracts instead.
Use the official Places API when you need billed, per-place lookups tied to a Google Cloud project. Use this Actor when you need a keyword-and-area sweep of many places at once, with the booking-platform breakdown Google's own API doesn't expose.
💡 How to use data extracted from Google Maps?
🏢 Restaurant, salon and clinic tech vendors
Filter bookingPresence to bookable_only and bookingProviders to a competitor's domain (e.g. ["opentable"]) to build a switch-target list: every venue currently running a named competitor's booking platform, with name, full_address and phone ready for outreach and booking_provider_names confirming which platform to pitch against.
📈 Booking and delivery aggregators
Run the same keyword/area sweep with bookingPresence set to not_bookable_only. The output is the actual sales pipeline: venues Google shows no reservation or ordering action for at all, which has_booking_action == false on every row confirms without needing to check each listing by hand.
📊 Market researchers and analysts
Sweep several cities or categories (e.g. hair salon, dentists, restaurants) and compare the share of has_booking_action == true rows and the booking_channel split per category or metro — a density and adoption view of who has moved online-booking to a third-party platform versus their own site versus nothing at all.
🤖 AI agents and automated pipelines
Because the Actor is a standard Apify Actor, it's callable from any agent framework as an HTTP-triggered run: pass keywords/locations as tool parameters, poll the run, and read the dataset back as structured JSON for RAG context or downstream enrichment — no scraping or HTML-parsing logic to maintain on the agent side.
🔼 Input sample
Read directly from .actor/actor.json. keywords is the only required field.
| Parameter | Required | Type | Description | Example value |
|---|---|---|---|---|
keywords | Yes | array of strings | One search term per line — e.g. restaurants, italian restaurant, sushi, hair salon, dentists. | ["restaurants"] |
locations | No | array of strings | Free-text areas — e.g. New York, Brooklyn NY, London, Kyoto Japan. Each is resolved to a bounding box and swept with a grid of map searches. | ["New York"] |
bookingPresence | No | string (enum) | all keeps everything; bookable_only keeps only venues with a working online booking action; not_bookable_only keeps only venues with none at all. | "all" |
bookingProviders | No | array of strings | Platform domains to keep, e.g. opentable.com, resy.com. A bare name like opentable also matches opentable.co.uk. Empty keeps every platform. | [] |
includeProviderLogos | No | boolean | Adds provider_logo_urls (Google-hosted 80×80 platform logos). Off by default — only useful for building a UI. | false |
maxResults | No | integer (1–10000) | Total unique places across all search terms, areas and links. Duplicates are merged on Google place_id. | 20 |
restrictToRequestedArea | No | boolean | Discards places outside the geocoded bounding box of the area you asked for. | true |
deepTileScan | No | boolean | Triples the places examined per search point. Applied automatically whenever a booking filter is active. | false |
urls | No | array of strings | Google Maps links, e.g. https://www.google.com/maps/search/restaurants/@40.7128,-74.0060,13z. | [] |
proxyConfiguration | No | object | Your proxy groups and country, passed through unchanged to every request. | {"useApifyProxy": true} |
{"keywords": ["restaurants"],"locations": ["New York"],"bookingPresence": "bookable_only","bookingProviders": ["opentable", "resy.com"],"maxResults": 50,"restrictToRequestedArea": true,"deepTileScan": false,"urls": [],"proxyConfiguration": { "useApifyProxy": true }}
Common pitfall: urls only supports /maps/search/<terms>/@lat,lng,zoom and /maps/place/<Name>/@lat,lng,zoom links. A link copied from Maps' "Share" button that identifies a place only by place_id, ftid, or cid is not supported and is skipped with an error in the run log — paste the address-bar URL from a search or place page instead.
🔽 Output sample
Every run pushes one dataset item per unique place as typed, normalized JSON — no HTML, no nested scraping needed. Export straight from the Apify Console or API as JSON, CSV, Excel, or XML.
{"rowType": "place","name": "Katz's Delicatessen","full_address": "205 E Houston St, New York, NY 10002","street_address": "205 E Houston St","city": "New York","state": "New York","zip": "10002","country_code": "US","phone": "(212) 254-2246","website": "https://www.katzsdelicatessen.com/","avg_rating": 4.5,"tags": ["Deli"],"place_id": "ChIJCar0f49ZwokR6ozLV-dHNTE","lat": 40.7223,"long": -73.9874,"hours": [{ "day": "Sunday", "hours": "8 AM-10:45 PM", "opens_at": "08:00", "closes_at": "22:45" }],"has_booking_action": true,"booking_channel": "third_party","booking_provider_count": 1,"booking_providers": ["opentable.com"],"booking_provider_names": ["OpenTable"],"booking_domains": ["opentable.com"],"booking_urls": ["https://www.opentable.com/r/katzs-delicatessen"],"google_reserve_url": "https://www.google.com/maps/reserve/v/dine/c/abc123","booking_action_labels": ["Reserve a table"],"provider_logo_urls": [],"search_term": "restaurants","search_area": "New York"}
🎯 How do you filter and target specific places?
Four real controls determine what ends up in your dataset:
- Keyword vs. URL.
keywords+locationsruns a category sweep across a grid of map points — the right choice for "every restaurant in Chicago."urlstargets a specific Maps search or place link directly and skips geocoding — the right choice when you already have a Maps URL in hand and want that exact scope, not a citywide sweep. - Area precision.
locationsfree text is geocoded to a bounding box and padded before the sweep starts;restrictToRequestedArea(on by default) then discards any place outside that box, so a "New York" search doesn't leak New Jersey venues. Turn it off only if you'd rather see everything Google's radiating search returns. - Booking-status targeting.
bookingPresencesplits the output into bookable-only, no-booking-only, or everything;bookingProvidersnarrows further to specific platform domains. Either filter automatically triples the depth of each map point scanned (the same effect asdeepTileScan), since a strict filter needs a bigger pool of raw places to draw from. - Volume.
maxResultscaps total unique places (1–10,000) across every keyword/location/URL combination, deduplicated onplace_id. The budget is split across your combinations as the run progresses, and a booking filter searches more of the map — it never silently returns fewer rows than you asked for without a reason logged.
{ "keywords": ["hair salon"], "locations": ["Chicago"], "bookingPresence": "bookable_only", "maxResults": 200 }
{ "keywords": ["restaurants"], "locations": ["London"], "bookingPresence": "bookable_only", "bookingProviders": ["opentable"], "maxResults": 100 }
{ "urls": ["https://www.google.com/maps/search/dentists/@34.0522,-118.2437,13z"], "keywords": ["dentists"], "bookingPresence": "not_bookable_only", "maxResults": 50 }
🔗 Want to try other Google Maps scrapers?
This account doesn't currently list another Google Maps scraper, but if you're building out a directory-and-leads workflow, these two cover adjacent ground:
| Scraper | What it extracts |
|---|---|
| Tripadvisor Review Scraper: Photo & Visual Content Filters | Hospitality reviews and visual content from Tripadvisor listings |
| Otomoto.pl Scraper With Dealer Contact Leads | Vehicle listings plus the dealer's phone, address and storefront behind each one |
🔌 How to extract Google Maps data programmatically
This Actor runs like any Apify Actor: start it from the Apify Console, via the apify_client SDK, or with a direct API call, and read results back as structured JSON from the run's dataset.
Python example
from apify_client import ApifyClientclient = ApifyClient("<APIFY_API_TOKEN>")run = client.actor("<username>/google-maps-extractor-with-reservation-order-online-links").call(run_input={"keywords": ["restaurants"],"locations": ["New York"],"bookingPresence": "bookable_only","maxResults": 100,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["name"], item["booking_channel"], item["booking_urls"])
Export to spreadsheets or CRM
Every dataset can be exported directly as CSV or Excel from the Apify Console or API — map name, full_address, phone and website to your CRM's contact columns, and booking_channel / booking_provider_names to a custom field for lead segmentation.
⚖️ Is it legal to scrape Google Maps?
Yes — this Actor reads publicly rendered Google Maps listings, the same business information (name, address, phone, hours, booking links) any visitor's browser receives when they search Maps. These are business directory records, not personal profiles, so the relevant framework is Google's own Terms of Service and database/intellectual-property rights around the Maps platform, not GDPR or CCPA. Automated collection at scale should still respect Google's Terms of Service, and results should not be republished as a competing map product. Consult legal counsel for commercial applications involving bulk storage or redistribution of this data.
❓ FAQ
Does the output flag venues that have closed or moved?
No. This build does not extract a closed/business-status field — it returns whatever Google's live map-search payload contains for each place at request time. Permanently closed venues typically stop appearing in Maps search results at all rather than being flagged in the data, so treat every row as current as of the run.
Can I get the booking/reservation link along with the main listing?
Yes, on the same row, from the same request. has_booking_action, booking_channel, booking_urls, booking_domains, booking_provider_names and google_reserve_url are all populated from the same Google Maps response the place data comes from — no second request per place, no extra credit. Coverage varies by category: Google's own input description reports the booking block was present on 44.0% of places in an 840-place measured sample, ranging from 90.8% for London Italian restaurants down to 0.8% for New York hotels. has_booking_action is filled on every row (true or false either way), so filtering never returns a blank column.
How accurate is the contact and booking data?
The Actor returns data exactly as Google's Maps payload carries it at request time — it does not call the venue, the booking platform, or the venue's own site to verify anything. Phone numbers, websites and booking links are only as current as Google's own listing; treat a batch of leads with the usual validation step (a deliverability or reachability check) before an outreach campaign.
How many places can I get per run?
maxResults accepts 1 to 10,000 and defaults to 20. That cap is a total across every keywords × locations pair and every urls entry combined, deduplicated on Google's place_id — not a per-search-term limit. A tight bookingPresence filter searches more of the map to fill the same target rather than returning fewer rows, and the run log reports how many places were found, filtered, and discarded as duplicates or out-of-area.
How do I build a list of venues with no online booking at all?
Set bookingPresence to not_bookable_only. The Actor automatically scans each map point more deeply (the same 3x multiplier deepTileScan applies) whenever a booking filter is active, since discarding most of what it finds needs a bigger raw pool to draw from — you don't need to set deepTileScan yourself for this to work.
Does google-maps-extractor-with-reservation-order-online-links work with Claude, ChatGPT, and AI agent frameworks?
It isn't currently reachable through an MCP server. It is callable as a standard HTTP-triggered Apify Actor by any agent framework that can make an authenticated API call and poll for run completion — via apify_client, a direct REST call, or Apify's own integrations.
Can I use this without a Google API key or developer account?
Yes. No Google account, API key, or Places API billing is required — only an Apify account. Apify Proxy is enabled by default in the input; the Actor escalates from datacenter to residential exits on its own if Google starts refusing requests, so no proxy setup is required to get started either.
✅ Conclusion
google-maps-extractor-with-reservation-order-online-links turns a Google Maps keyword-and-area sweep into structured leads that already know how each venue takes bookings — the reservation link, the platform behind it, and Google's own Reserve URL, with no extra request and no extra charge over the base place data. It's built for restaurant-tech and booking-platform vendors building switch-target or prospecting lists, and for researchers tracking booking-platform adoption across cities and categories. Start a run from the Apify Console with a keyword and a city, or call it through apify_client, and read the results back as clean JSON.