Google Maps Business Scraper | $1 per 1,000 avatar

Google Maps Business Scraper | $1 per 1,000

Pricing

$1.00 / 1,000 unique business results

Go to Apify Store
Google Maps Business Scraper | $1 per 1,000

Google Maps Business Scraper | $1 per 1,000

Scrape unique Google Maps business listings by city, region, or country. Export names, addresses, phones, websites, ratings, review counts, opening hours, photos, and coordinates. Fast, API-ready, and priced at $1 per 1,000 successful results.

Pricing

$1.00 / 1,000 unique business results

Rating

0.0

(0)

Developer

DataScraperES

DataScraperES

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

3 days ago

Last modified

Share

Scrape unique Google Maps business listings from cities, regions, or whole countries. Export business names, addresses, phone numbers, websites, ratings, review counts, opening hours, photos, categories, and coordinates in a clean dataset ready for lead generation, local SEO, market research, or automation.

Price: $0.001 per unique business successfully written to the dataset — $1.00 per 1,000 results. There is no Actor-start fee.

No Google Places API key, OAuth setup, or external account is required.

What this Actor does

Provide one or more geographic locations and one or more Google Maps search queries. The Actor searches every requested query in every location, expands coverage across the target area, filters geographic spillover, and writes unique businesses to the default Apify dataset.

For example, these inputs:

  • locations: Madrid, Barcelona
  • queries: dentists, orthodontists

produce searches for both queries in both cities. If the same business appears in multiple searches, it is written and billed only once because results are deduplicated globally by Google Place ID.

Key benefits

  • Global geographic targeting: search cities, municipalities, regions, states, or countries.
  • Coverage beyond a single Google Maps search: the target area is divided automatically into geographic sectors.
  • Strict area filtering: businesses outside the resolved target boundary are excluded.
  • Unique results: duplicate Place IDs found across sectors, queries, and locations are not written twice.
  • Simple pricing: one chargeable event at $0.001 per unique dataset item.
  • Cost controls: use maxResults and Apify's Maximum cost per run.
  • Structured output: 24 documented fields per business.
  • Easy automation: run from Apify Console, API, CLI, schedules, webhooks, Make, Zapier, or your own application.

Best use cases

  • Build local business prospect lists for sales and outreach.
  • Discover companies by category in a city, region, or country.
  • Compare market density, ratings, and review counts.
  • Find business websites and public phone numbers.
  • Enrich a CRM with Google Maps identifiers and location data.
  • Create or maintain local business directories.
  • Research competitors and branch coverage.
  • Map retail, hospitality, healthcare, or service-business locations.
  • Prepare location datasets for GIS and business intelligence tools.

This Actor returns Google Maps business data. It does not crawl business websites for email addresses or social profiles, and it does not extract individual Google reviews.

Quick start

  1. Open the Actor's Input tab.
  2. Enter a location such as Madrid.
  3. Enter a search query such as dentists.
  4. Keep countryCode aligned with the location, for example ES.
  5. Set Max Results to 20 for a small test.
  6. Click Start.
  7. Open the Output or Dataset tab to inspect and download the results.

Minimal input:

{
"locations": ["Madrid"],
"queries": ["dentists"],
"language": "es",
"countryCode": "ES",
"maxResults": 20
}

At the configured price, a completed 20-result run costs $0.02 in Actor event charges.

Input reference

FieldTypeRequiredDefaultDescription
locationsArray of stringsYesCities, regions, states, or countries to search. Use a country name for the widest coverage and highest potential number of results.
queriesArray of stringsYesGoogle Maps search terms. Every query runs in every location until the global result limit is reached.
languageStringYesesLanguage used for Google Maps results. Choose one of 100 available languages.
countryCodeStringYesESCountry used to disambiguate and constrain locations. Choose one of 100 available countries and markets.
maxResultsIntegerNo1000Global maximum number of unique businesses written across the complete run. 0 means unlimited.

Locations

Use clear geographic names that match countryCode:

{
"locations": ["Madrid", "Barcelona", "Valencia"],
"countryCode": "ES"
}

Locations can have different geographic sizes:

  • city: Chicago
  • county: Cook County
  • state or region: California
  • country: Singapore

For the widest coverage and highest potential number of results, enter the country name itself in locations and select its matching countryCode:

{
"locations": ["Spain"],
"countryCode": "ES",
"maxResults": 10000
}

This searches across the country instead of limiting discovery to one city or region. Selecting ES without using Spain as the location does not turn a city search into a country search. Country-wide runs usually take longer and can cost more, while maxResults remains the global output and billing limit.

For ambiguous names, include the state or region in the location text, for example Springfield, Illinois.

Queries

Queries work like searches a person would type into Google Maps:

{
"queries": [
"Italian restaurants",
"dental clinics",
"coworking spaces"
]
}

Specific queries usually produce more relevant datasets than broad terms. Related queries can improve discovery, but a business matched by several queries is still stored only once.

Language

The input form provides a validated dropdown with 100 unique language options. The most commonly used options appear first, followed by the extended list:

af, am, ar, az, be, bg, bn, bs, ca, cs, cy, da, de, el, en, es, et, eu, fa, fi, fil, fr, ga, gl, gu, ha, he, hi, hr, hu, hy, id, ig, is, it, ja, jv, ka, kk, km, kn, ko, ku, ky, lb, lo, lt, lv, mg, mi, mk, ml, mn, mr, ms, mt, my, nb, ne, nl, nn, no, ny, or, pa, pl, ps, pt, ro, ru, rw, sd, si, sk, sl, sm, sn, so, sq, sr, st, su, sv, sw, ta, te, tg, th, tk, tl, tr, tt, uk, ur, uz, vi, xh, yo, zh, and zu.

Language affects the text returned by Google Maps, including categories, descriptions, and opening-day labels where available.

Country code

The input form provides a validated dropdown with 100 unique countries and markets. Each option shows its name and two-letter ISO 3166-1 code, preventing mistyped or unsupported values. Common examples include:

  • ES — Spain
  • US — United States
  • GB — United Kingdom
  • BR — Brazil
  • DE — Germany
  • JP — Japan
  • AU — Australia

Available codes:

AE, AM, AO, AR, AT, AU, AZ, BD, BE, BH, BO, BR, BW, CA, CH, CI, CL, CM, CN, CO, CR, CU, CZ, DE, DK, DO, DZ, EC, EG, ES, ET, FI, FR, GB, GE, GH, GR, GT, HN, HR, HU, ID, IE, IL, IN, IQ, IT, JM, JO, JP, KE, KR, KW, KZ, LB, LK, MA, MX, MY, MZ, NA, NG, NI, NL, NO, NP, NZ, OM, PA, PE, PH, PK, PL, PT, PY, QA, RO, RS, RU, RW, SA, SE, SG, SN, SV, TH, TN, TR, TT, TZ, UA, UG, US, UY, UZ, VE, VN, ZA, ZM, and ZW.

The country code applies to every location in the run. Use separate runs when searching locations in different countries.

Maximum results

maxResults is a global limit, not a per-query or per-location limit. Processing stops after that many unique businesses have been successfully written to the dataset.

If you provide three locations and four queries with maxResults: 1000, the combined output from all 12 location-query combinations is capped at 1,000 unique businesses.

Use 0 only when you intentionally want the complete planned scan. For large areas, also set an appropriate run timeout and Maximum cost per run in Apify's run options.

Input recipes

One category in one city

{
"locations": ["London"],
"queries": ["accounting firms"],
"language": "en",
"countryCode": "GB",
"maxResults": 500
}
{
"locations": ["Miami, Florida"],
"queries": [
"dentists",
"orthodontists",
"dental implants"
],
"language": "en",
"countryCode": "US",
"maxResults": 2000
}

Region-wide market research

{
"locations": ["Andalusia"],
"queries": [
"hotels",
"hostels",
"holiday apartments"
],
"language": "es",
"countryCode": "ES",
"maxResults": 10000
}

Country-scale scan

{
"locations": ["Singapore"],
"queries": ["restaurants"],
"language": "en",
"countryCode": "SG",
"maxResults": 0
}

Country and large-region scans can require a longer timeout. Start with a capped test before running without a result limit.

Output

Every accepted business is stored as one item in the default dataset. You can inspect results as a table in Apify Console or export them as JSON, JSONL, CSV, Excel, XML, or RSS.

Example result

{
"name": "Example Dental Clinic",
"placeId": "ChIJEXAMPLE",
"googleMapsUrl": "https://www.google.com/maps/place/?q=place_id:ChIJEXAMPLE",
"address": "Calle de Ejemplo, 10",
"city": "Madrid",
"region": "Madrid",
"postalCode": "28001",
"countryCode": "ES",
"phone": "910 000 000",
"website": "https://example.com/",
"avgRating": 4.7,
"totalReviews": null,
"priceRange": null,
"tags": ["Dentista", "Clínica dental"],
"description": "",
"businessPhoto": "https://lh5.googleusercontent.com/.../s800/photo.jpg",
"photoUrls": [
"https://lh5.googleusercontent.com/.../s800/photo.jpg"
],
"hours": [
{
"day": "lunes",
"hours": "9:00–20:00",
"open24Hour": 9,
"close24Hour": 20
}
],
"lat": 40.4168,
"long": -3.7038,
"discoveryQuery": "dentists",
"searchLocation": "Madrid",
"searchCoordinates": "40.4200,-3.7000",
"scrapeTimestamp": "2026-07-23T11:58:22.031656+02:00"
}

Complete output field reference

FieldTypeObserved presenceDescription
nameString100%Business name displayed on Google Maps. Required for every accepted result.
placeIdString100%Stable Google Maps Place ID used to deduplicate results within the run. Required.
googleMapsUrlString100%Direct Google Maps link generated from placeId.
addressString or null100%Street address or the most complete formatted address available.
cityString or null100%City, municipality, or locality extracted from the listing.
regionString or null100%Region, state, province, or first-level administrative area.
postalCodeString or null99.70%Postal or ZIP code.
countryCodeString or null100%Two-letter ISO country code associated with the result.
phoneString or null97.75%Public phone number shown on Google Maps. Formatting is returned as displayed and may not include an international prefix.
websiteString or empty84.57%Public website linked from the listing. Tracking redirects are removed when possible.
avgRatingNumber or null97.83%Average Google Maps rating, normally from 1.0 to 5.0.
totalReviewsInteger or null2.72%Review-count value when present in the returned listing payload. Individual review text and reviewer data are not collected.
priceRangeString or null0%Price-level text when exposed. It was not present in the measured sample.
tagsArray of strings100%Business categories associated with the listing, in the selected language.
descriptionString or empty0%Business description when exposed. It was empty in the measured sample.
businessPhotoString or null91.19%Main business photo URL, normalized to an 800-pixel Google image URL when available.
photoUrlsArray of strings91.19%Unique photo URLs found for the business. An empty array means no photo URL was exposed.
hoursArray of objects94.37%Displayed opening-hours entries returned for the listing. An empty array means hours were not exposed.
latNumber100%Latitude. A candidate without valid coordinates is not accepted.
longNumber100%Longitude. A candidate without valid coordinates is not accepted.
discoveryQueryString100%First input query that added this unique business to the dataset.
searchLocationString100%Input location being processed when the business was first accepted.
searchCoordinatesString100%Latitude and longitude of the search sector that discovered the business, formatted as lat,lng.
scrapeTimestampISO 8601 string100%Collection timestamp including its UTC offset.

How to interpret field availability

Only name and placeId are contractual required fields. Other values depend on the listing, business category, country, selected language, and the data returned by Google Maps at collection time.

The percentages above are measured values, not guaranteed fill rates. They come from 10,000 row observations collected on July 23, 2026 across ten repeated 1,000-result runs for dentistas in Madrid:

  • 100% observed: identity, link, address components, categories, coordinates, discovery context, and timestamp
  • 97-99.99% observed: postal code, phone, and average rating
  • 80-96.99% observed: website, photos, and opening hours
  • below 5% observed: total review count, price range, and description

This sample is useful for planning an integration, but it is not representative of every category or country. For example, restaurants may expose price information more often, while listings without an official website will naturally leave website empty.

Missing-value conventions

The Actor does not invent, predict, or enrich missing Google Maps values:

  • missing text can be null or an empty string ""
  • missing arrays such as photoUrls and hours are normally []
  • missing numeric values such as avgRating or totalReviews are null
  • 0 is a valid number and should not automatically be treated as missing

When importing CSV or Excel exports, configure your destination to accept empty cells for optional fields. When consuming JSON, check both null and empty strings or arrays.

Opening-hours object

Each item inside hours can contain:

Nested fieldTypeDescription
dayString or nullLocalized day label returned using the selected input language.
hoursString or nullHuman-readable interval such as 10:00–20:00. Use this value when minutes or split periods matter.
open24HourInteger or nullOpening-hour component in 24-hour format.
close24HourInteger or nullClosing-hour component in 24-hour format.

Google Maps may return only the hours entries available in the current search payload rather than a complete seven-day schedule. Do not assume seven items will always be present.

Identity, discovery, and geographic fields

placeId identifies a Google Maps listing. It is the recommended key for merging exports or comparing repeated runs. Different branches of the same brand normally have different Place IDs and remain separate businesses.

lat and long describe the business itself. searchCoordinates describes the search sector that discovered it; it is not a replacement for the business coordinates. discoveryQuery and searchLocation explain why the result is present in a multi-query or multi-location run.

Pricing and billing

The Actor uses pay-per-event pricing with one billable event:

EventPriceWhen it is charged
business-result$0.001Once for each unique business successfully written to the default dataset

There is no Actor-start charge and no second dataset-item charge.

You are not charged a business-result event for:

  • duplicate Place IDs found again in another sector or query
  • businesses filtered out because they are outside the target area
  • failed search requests
  • empty search responses
  • candidates that are not written to the dataset

Example costs:

Unique resultsActor event charge
20$0.02
100$0.10
1,000$1.00
5,000$5.00
10,000$10.00
50,000$50.00

Control your maximum cost

Use both available safeguards:

  1. Set maxResults to the largest dataset you want.
  2. Set Maximum cost per run in Apify's run options.

The Actor checks the remaining pay-per-event capacity before starting additional work and stops gracefully when the configured charge limit is reached.

Coverage and deduplication

Geographic coverage

The Actor resolves each requested location, plans an area-appropriate search grid, and filters returned coordinates against the target boundary. This reduces the common Google Maps behavior of returning nearby businesses outside the requested city or region.

Where an exact geographic boundary is available, point-in-polygon filtering is used. Otherwise, the resolved bounding area is used. Results with missing or invalid coordinates are excluded because their location cannot be verified.

Unique business rules

Uniqueness is based on placeId across the entire run:

  • the same business found in several grid sectors is stored once
  • the same business found by several queries is stored once
  • the same business found through overlapping locations is stored once
  • separate branches with different Place IDs remain separate results

When a result matches more than one query, discoveryQuery records the query that first added it to the dataset.

Coverage expectations

Google Maps results are dynamic and can vary with query wording, language, location, availability, and upstream changes. No scraper can guarantee a permanent or exhaustive copy of every business. For broader discovery:

  • use the country name as the location when you want the widest geographic coverage and the highest potential result count
  • combine several specific, related queries
  • scan the correct geographic level
  • use a sufficient timeout
  • compare repeated runs when monitoring changes over time

Performance and run timeout

The default Actor memory is 512 MB and the default timeout is 300 seconds. Small capped runs usually finish well within that window. Larger grids may need more time.

WorkloadSuggested timeout
Small test, up to 100 results5 minutes
City scan, up to 1,000 results5-10 minutes
Large city or region, up to 10,000 results15-30 minutes
Unlimited region or country scan30-60 minutes or more

Actual duration depends on the target area's size, number of queries, number of locations, result cap, and Google Maps response conditions.

If a run reaches its timeout, increase the timeout in Run options and start a new run. Do not use unlimited mode for a large area until a capped test has confirmed the expected coverage and cost.

Run through the API

Actor identifier:

datascraperes/actor-google-maps

Synchronous HTTP request

This endpoint waits for the run and returns the default dataset items:

curl -X POST \
"https://api.apify.com/v2/acts/datascraperes~actor-google-maps/run-sync-get-dataset-items?timeout=300" \
-H "Authorization: Bearer YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"locations": ["Madrid"],
"queries": ["dentists"],
"language": "es",
"countryCode": "ES",
"maxResults": 20
}'

For large runs, start the Actor asynchronously and poll the run status instead of waiting on a synchronous HTTP connection.

Python

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("datascraperes/actor-google-maps").call(
run_input={
"locations": ["Madrid"],
"queries": ["dentists"],
"language": "es",
"countryCode": "ES",
"maxResults": 20,
}
)
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(f"Downloaded {len(items)} unique businesses")

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('datascraperes/actor-google-maps').call({
locations: ['Madrid'],
queries: ['dentists'],
language: 'es',
countryCode: 'ES',
maxResults: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Downloaded ${items.length} unique businesses`);

Apify CLI

Save the input as input.json, then run:

apify actors call datascraperes/actor-google-maps \
--input-file input.json \
--output-dataset

Automation and integrations

Because results are stored in the default Apify dataset, you can:

  • schedule recurring runs in Apify Console
  • trigger workflows through webhooks
  • download JSON, CSV, or Excel files
  • connect the Actor to Make or Zapier
  • import results into Google Sheets, Airtable, a CRM, or a database
  • use the Actor from an AI agent through Apify integrations
  • combine it with another Actor that enriches the returned websites

When scheduling repeated runs, each run creates its own dataset by default. Use placeId as the stable key when comparing or merging results across runs.

Troubleshooting

The location cannot be resolved

  • Check the spelling.
  • Ensure countryCode matches the location.
  • Add a state or region to ambiguous names.
  • Split locations from different countries into separate runs.

If none of the requested locations can be planned, the Actor fails explicitly instead of reporting a misleading successful empty run.

The run succeeded but returned no businesses

  • Try a broader or more common query.
  • Verify the selected language and country code.
  • Test the same search manually in Google Maps.
  • Use a city-level location before attempting a very small district.

An empty but successfully processed search is not billed as a business result.

Fewer businesses were returned than expected

  • Check whether maxResults or Maximum cost per run was reached.
  • Increase the run timeout for large areas.
  • Add related queries because Google Maps ranks different businesses for different search terms.
  • Remember that only businesses with a valid Place ID, name, and coordinates inside the target area are accepted.

A business has no phone number or website

Google Maps does not expose every field for every listing. Missing optional values can be returned as null, an empty string, or an empty array; the Actor does not invent or infer them. See How to interpret field availability for measured fill rates and handling guidance.

The same brand appears several times

Different physical branches normally have different Google Place IDs and are therefore valid separate results. Exact Place ID duplicates are removed.

The run stopped at a specific number of results

The run reached maxResults or the Apify maximum-charge limit. This is a successful controlled stop, not a scraper error.

A large scan timed out

Increase the timeout in Apify run options, reduce the number of location-query combinations, or split the workload into several runs.

FAQ

Do I need a Google Maps or Google Places API key?

No. The Actor does not require a Google API key or Google Cloud project.

Does it work worldwide?

Yes. Use a valid two-letter country code and a location name that can be resolved in that country. To maximize potential coverage, use the country name itself as the location. Large or complex areas can require longer runs and may cost more than a city search.

Are results unique?

Yes, within each run. Results are deduplicated by Google Place ID across all queries, sectors, and locations.

Are duplicate discoveries charged?

No. The business-result event is charged only when a unique item is successfully written to the default dataset.

Does it extract email addresses or social profiles?

No. It returns the public website and phone number shown by Google Maps. You can pass the website field to a separate enrichment workflow if needed.

Does it extract individual reviews?

No. It returns avgRating and totalReviews, not individual review text or reviewer profiles.

Can I search several countries in one run?

The public input uses one shared countryCode, so locations from different countries should be placed in separate runs.

Can I use it as an API?

Yes. You can start runs and retrieve datasets using the Apify REST API, Python client, JavaScript client, or CLI.

Can I schedule recurring Google Maps exports?

Yes. Use Apify schedules and optionally attach a webhook or integration to process the dataset after each successful run.

Is a result guaranteed to have every field?

No. name and placeId are required. All other fields depend on the information available for that business on Google Maps.

Responsible use

Use this Actor only for lawful purposes and in accordance with applicable terms, privacy rules, database rights, and data-protection laws. Business data can include personal data in some jurisdictions. You are responsible for determining the legal basis for collecting, storing, combining, and contacting people using the output.

Avoid excessive collection, secure downloaded datasets, keep data only as long as necessary, and honor valid deletion or opt-out requests where applicable.

Support

If you encounter a reproducible problem, open an issue from the Actor's Apify page and include:

  • the run ID
  • a sanitized copy of the input
  • the expected result
  • the observed result
  • whether the issue occurs consistently

Do not include API tokens, credentials, or confidential customer data.