Google Maps Scraper — Extract Business Data at Scale
Pricing
from $4.00 / 1,000 result scrapeds
Google Maps Scraper — Extract Business Data at Scale
Collect public Google Maps business listing data including names, categories, addresses, websites, ratings, review counts, hours, coordinates, and Maps URLs. Export structured data to JSON, CSV, or Excel.
Pricing
from $4.00 / 1,000 result scrapeds
Rating
0.0
(0)
Developer
Md Jakaria Mirza
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
4 days ago
Last modified
Categories
Share
Google Maps Scraper - Extract Business Data at Scale
Production-grade Apify Actor for scraping public Google Maps business listings worldwide. Enter a keyword and location, run a small test, then export clean business data to JSON, CSV, Excel, XML, or RSS from the Apify Dataset.
This Actor is built with Node.js 20, TypeScript, Apify SDK v3, Crawlee, and Playwright. It uses Apify residential proxies, session rotation, randomized delays, and resilient extraction logic for Google Maps result pages.
Apify Store Listing
Title: Google Maps Scraper - Extract Business Data at Scale
Short description: Scrape worldwide Google Maps listings with names, phones, websites, ratings, reviews, categories, hours, and coordinates. Export to CSV, JSON, or Excel.
Store description:
Google Maps Scraper - Extract Business Data at Scale helps teams collect structured local business data from Google Maps searches worldwide. Use it to find restaurants in London, dentists in Dubai, hotels in Tokyo, plumbers in Toronto, clinics in Berlin, or any other keyword/location combination. The Actor opens Google Maps in a real browser, scrolls the search feed, visits each business detail panel, and extracts practical B2B data including business name, address, phone, website, category, rating, reviews count, opening hours, coordinates, Google Maps ID, plus code, and Maps URL.
It supports batch scraping by combining multiple keywords with multiple locations in a single run. Locations can be cities, countries, postal codes, neighborhoods, addresses, latitude/longitude pairs, the built-in 169-city high_demand_markets preset, or the broader 171-city world_major_cities preset. Country targeting is optional: leave countryCode empty for worldwide location-text based searches, or set it to bias Google Maps and proxy country for a specific market.
The Actor uses Apify Pay Per Event + platform usage pricing. As of the last live check on 2026-06-29, the current pricing entry started on 2026-06-25: result-scraped at $0.004 per saved result and apify-actor-start at $0.001 per start event. The start event is charged by allocated memory (one event per GB, minimum one), and users also pay Apify platform usage generated by the run, such as compute and proxy traffic. Failed searches, empty locations, retries, and blocked pages do not create result-scraped events.
For first tests, keep the run small: one keyword, one location, maxResults 5 or less, maxCrawledPlacesPerQuery 5 or less, and scrapeDetails disabled unless you need phone/full-address enrichment.
Built for market research, local SEO audits, and retail site selection, this scraper is designed for repeatable production use and Apify Store publishing.
What It Extracts
- Business name
- Address (full street address from the place page when
scrapeDetailsis enabled) - Phone number (from the place page when
scrapeDetailsis enabled) - Website
- Category
- Rating
- Reviews count
- Opening hours
- Latitude and longitude
- Google Maps ID
- Plus code (from the place page when
scrapeDetailsis enabled) - Google Maps URL
- Keyword, location, query, and scrape timestamp
Worldwide Use
This Actor is not limited to Kolkata, India, the United States, or any single country. It works globally because:
- Search locations are free-form strings, e.g.
Paris, France,Sao Paulo, Brazil,Shibuya, Tokyo, Japan,Dubai Marina, UAE. - The built-in
high_demand_marketspreset covers 169 commercial cities where local business data, local SEO, and market research use cases are most common. - The built-in
world_major_citiespreset covers 171 big and famous cities across North America, Latin America, Europe, the Middle East, Africa, South Asia, East/Southeast Asia, and Oceania. countryCodeis optional and defaults to noglcountry bias.- The proxy country is not forced by default.
- If you set
countryCode, the Actor also uses that country for proxy targeting unless you explicitly overrideproxyConfig.apifyProxyCountry.
For best accuracy, include the country in each location. For example, use restaurants in Georgia, USA or restaurants Tbilisi, Georgia instead of only Georgia.
Preset Strategy
high_demand_markets: best default for broad coverage. Focuses on rich metro areas, business hubs, startup hubs, GCC markets, English-speaking countries, EU business centers, India metros, and fast-growing APAC/LATAM cities where customers commonly use local business data, local SEO, and market research data.world_major_cities: broader global coverage for users who want famous cities across more regions, including tourism, emerging markets, and general business hubs.none: use only custom locations when the customer already knows the exact target market.
Use Cases
- Local business data: build business listing datasets with names, phones, websites, addresses, and Maps URLs.
- Market research: compare competitor density, ratings, and categories by city or region.
- Local SEO audits: check business presence, category choices, and public NAP data.
- Territory planning: understand business distribution before entering a new market.
- Retail and real estate analysis: identify dense commercial clusters and underserved areas.
Pricing and cost control
This Actor uses Apify Pay Per Event + platform usage pricing. Prices can be changed only through Apify's pricing window or Support process, so always treat the live Console pricing as the source of truth before running large jobs.
| Event name | Price per event | 1,000 results | 10,000 results |
|---|---|---|---|
result-scraped | $0.004 active live | $4.00 | $40.00 |
apify-actor-start | $0.001 active live | n/a | n/a |
In addition to the event prices above, the user pays Apify platform usage generated by the run, including compute and proxy traffic. Residential proxy is recommended for Google Maps reliability, but it can increase run cost. For a default 2048 MB run, the start event may be counted as two GB-based events, so the effective default start charge is about $0.002.
The code charges only after a business record is extracted and before it is pushed to the dataset. If the charge budget is exhausted, the Actor stops gracefully. Dataset writes are retried after charging to reduce the risk of paid rows not being stored.
Cost-control tips:
- Start with one keyword and one location.
- Use
maxResults1-5 for a test run. - Keep
maxCrawledPlacesPerQueryclose tomaxResults. - Leave
locationPresetasnoneunless you intentionally want a large multi-city run. - Keep
scrapeDetails=falsefor cheaper list-style runs; enable it only when phone/full address/plus code matter.
Input
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
keywords | array | yes | none | Business types or search terms. |
locations | array | no | none | Custom cities, regions, postal codes, addresses, or lat,lon pairs anywhere in the world. Required only when no preset is selected. |
locationPreset | string | no | none | Use high_demand_markets for 169 commercial hotspots, world_major_cities for broad global coverage, or none for custom locations only. Custom locations are added on top. |
maxResults | integer | no | 5 | Maximum saved rows per keyword/location pair. Start with 1-5 for tests; increase for production. Allowed: 1-5000. |
maxCrawledPlacesPerQuery | integer | no | 5 | Maximum place cards/detail pages to inspect per query. Keep close to maxResults for low-cost tests; set higher only when many listings may be closed or duplicates. |
language | string | no | en | Result language code, e.g. en, de, es, fr, ja. |
countryCode | string | no | none | Optional 2-letter country bias, e.g. gb, de, jp, ae. |
skipClosedBusinesses | boolean | no | true | Skip listings marked permanently closed. |
scrapeDetails | boolean | no | false | Visit each place page when phone or full address is missing from the list view; also captures the plus code. Keep disabled for faster/cheaper list-only runs. |
proxyConfig | object | no | Residential Apify proxy | Apify proxy configuration. Leave country empty for global runs. |
The Actor removes duplicate keywords and locations. The keyword/location cartesian product is capped at 1,000 queries to prevent accidental huge runs. With either large preset, up to 5 keywords fit under the 1,000-query cap. For first tests, keep locationPreset as none and use 1-2 custom locations.
When scrapeDetails is enabled, the Actor performs an extra navigation to each place's individual Google Maps page whenever the list view did not expose a phone number or full address. Each detail page has a 10-second timeout. If the detail page fails, the Actor keeps the list-view data so no record is dropped.
Example Inputs
Quick Low-Cost Test
{"keywords": ["coffee shop"],"locations": ["London, UK"],"locationPreset": "none","maxResults": 5,"maxCrawledPlacesPerQuery": 5,"language": "en","countryCode": "gb","skipClosedBusinesses": true,"scrapeDetails": false,"proxyConfig": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"]}}
High-Demand Markets Batch
{"keywords": ["coffee shop"],"locationPreset": "high_demand_markets","maxResults": 25,"maxCrawledPlacesPerQuery": 50,"language": "en","skipClosedBusinesses": true,"scrapeDetails": true,"proxyConfig": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"]}}
Broad World Cities Batch
{"keywords": ["restaurant"],"locationPreset": "world_major_cities","maxResults": 25,"maxCrawledPlacesPerQuery": 50,"language": "en","skipClosedBusinesses": true,"scrapeDetails": true}
Custom Global Batch
{"keywords": ["coffee shop", "coworking space"],"locations": ["London, UK", "Berlin, Germany", "Tokyo, Japan", "Dubai, UAE"],"maxResults": 50,"maxCrawledPlacesPerQuery": 100,"language": "en","skipClosedBusinesses": true,"scrapeDetails": true,"proxyConfig": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"]}}
Country-Biased Run
{"keywords": ["dentist"],"locations": ["Manchester", "Birmingham", "Leeds"],"maxResults": 200,"maxCrawledPlacesPerQuery": 300,"language": "en","countryCode": "gb","skipClosedBusinesses": true,"scrapeDetails": true}
Coordinate Search
{"keywords": ["hotel"],"locations": ["25.2048,55.2708", "48.8566,2.3522"],"maxResults": 100,"scrapeDetails": true}
Fast List-Only Run
{"keywords": ["pizza"],"locations": ["New York, USA"],"maxResults": 200,"scrapeDetails": false}
Output dataset
The default Google Maps Business Listings dataset view is built for business research, local SEO, and market analysis exports. It shows business name, category, rating, review count, address, phone, website, opening hours, Google Maps URL, keyword, location, and scraped timestamp. The full JSON output also includes coordinates, Maps ID, Plus Code, and the combined query when available.
Verified small-run sample from an existing successful run:
{"title": "Hideaway Coffee House","address": "7 Farrier's Psge, London W1D 7DP","phone": null,"website": "https://www.instagram.com/hideawaycoffee/","category": "Coffee shop","rating": 4.7,"reviewsCount": 1241,"hours": ["Sunday: 9 am-5 pm","Monday: 7:30 am-5 pm","Tuesday: 7:30 am-5 pm"],"latitude": 51.5113375,"longitude": -0.1352386,"mapsId": "0x4876057cc8805b41:0x60c897012e57e344","plusCode": null,"url": "https://www.google.com/maps/place/Hideaway+Coffee+House/data=!4m7!3m6!1s0x4876057cc8805b41:0x60c897012e57e344!8m2!3d51.5113375!4d-0.1352386!16s%2Fg%2F11g4lm05yc!19sChIJQVuAyHwFdkgRRONXLgGXyGA","keyword": "coffee shops","location": "London","query": "coffee shops London","scrapedAt": "2026-06-21T08:02:48.057Z"}
API Example
curl -X POST "https://api.apify.com/v2/acts/fascinating_lentil~google-maps-scraper/runs?token=YOUR_API_TOKEN" \-H "Content-Type: application/json" \-d '{"keywords": ["coffee shop"],"locations": ["London, UK"],"maxResults": 5,"maxCrawledPlacesPerQuery": 5,"language": "en","scrapeDetails": false}'
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });const run = await client.actor('fascinating_lentil/google-maps-scraper').start({keywords: ['coffee shop'],locations: ['London, UK'],maxResults: 5,maxCrawledPlacesPerQuery: 5,language: 'en',scrapeDetails: false,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(`Got ${items.length} businesses`);
How It Works
- Validates input with clear errors.
- Builds one Google Maps search URL per keyword/location pair.
- Adds
hllanguage and optionalglcountry bias only when provided. - Runs Playwright through Apify residential proxies and Crawlee sessions.
- Scrolls Google Maps results until enough places are loaded or the feed ends.
- Opens each listing detail panel and extracts business data.
- If
scrapeDetailsis enabled and phone or address is still missing, visits the place's individual Google Maps page with a 10-second timeout to retrieve phone, full address, and plus code. - Deduplicates records by Maps ID and title.
- Charges
result-scrapedand writes records to the Apify Dataset.
Anti-Bot Handling
- Apify residential proxy support.
- Optional country-matched proxy targeting.
- Session pool with limited usage per session.
- Randomized scroll, click, and extraction delays.
- Retry support for transient blocks and navigation failures.
- Graceful field-level fallback to
nullwhen optional data is unavailable.
Project Structure
google-maps-scraper/.actor/actor.jsonDockerfilesrc/main.tsroutes.tstypes.tsINPUT_SCHEMA.jsoninput.jsonpackage.jsonpackage-lock.jsonREADME.mdPROMOTION-NOTES.mdtsconfig.json
Local Development
npm cinpm run buildnpx playwright install chromiumnpm start
For Apify local runs, put your input in storage/key_value_stores/default/INPUT.json or use the included input.json as a starting point.
Suggested Next Updates
- Add live smoke-test fixtures for 3 countries before each release.
- Add optional review scraping as a separate PPE event, e.g.
review-scraped. - Add region presets such as North America, Europe, GCC, APAC, and LATAM.
- Add a per-query summary dataset or key-value output for marketplace-quality reporting.
Known Limits
scrapeDetailsdefaults tofalsefor faster list-style runs. When it is enabled, keepmaxCrawledPlacesPerQuerysmall because each detail page may add extra navigation time.- The current default run timeout is 1 hour (
timeoutSecs: 3600in.actor/actor.json) and the per-query handler timeout is 10 minutes. Use one keyword, one location, and low caps for tests; split larger multi-city jobs into separate runs. - Detail-page enrichment only fires when phone or full address is missing from the list view, so runs against well-structured queries where the list view already exposes the phone will not pay the extra navigation cost.
- Duplicate detection is based on
mapsId(or title whenmapsIdis unavailable). Two chain stores with the same business name but differentmapsIdare kept as separate records.
Legal And Ethical Use
Use this Actor for legitimate business intelligence, local business data collection, local SEO, and market research. You are responsible for complying with Google Maps terms, privacy laws, anti-spam rules, GDPR, CAN-SPAM, and local outreach regulations in every country where you use the data.
Responsible Use
This Actor is intended for lawful collection of publicly available information only. Users are responsible for ensuring their use complies with the source website's terms, robots.txt, applicable privacy laws, including India's DPDP Act, and all local regulations.
Do not use this Actor to collect, store, sell, or misuse personal data without a lawful basis. The Actor author is not responsible for misuse by end users.
License
Apache-2.0. See LICENSE.