Google Maps Scraper - Business Leads, Phones & Opening Hours avatar

Google Maps Scraper - Business Leads, Phones & Opening Hours

Pricing

$2.50 / 1,000 place scrapeds

Go to Apify Store
Google Maps Scraper - Business Leads, Phones & Opening Hours

Google Maps Scraper - Business Leads, Phones & Opening Hours

Google Maps scraper for local business lists. Search by keyword and city and get name, category, address, phone, website, rating, review count, opening hours and coordinates for every place, as JSON, CSV or Excel. For lead lists, market mapping and local research.

Pricing

$2.50 / 1,000 place scrapeds

Rating

0.0

(0)

Developer

SR

SR

Maintained by Community

Actor stats

0

Bookmarked

92

Total users

15

Monthly active users

8 days ago

Last modified

Share

Google Maps Scraper — Business Leads, Phones and Opening Hours

This Google Maps scraper turns a search such as "plumbers Austin TX" into a clean list of local businesses: name, category, full address, phone number, website, rating, review count, opening hours and coordinates for every place. Use it to build lead lists, map a local market, or keep a business directory current, and export the result as JSON, CSV or Excel. It keeps the established input and dataset format of s-r/free-google-maps-scraper, so saved tasks and integrations keep working.

What the Google Maps scraper returns

For each search you get the places Google Maps lists for it, in the order Google shows them, one dataset row per place. Every row has the same 28 established fields plus four identification fields, so a spreadsheet or database import never has to guess at the shape:

  • Identity: name, fid, place_id, kgmid
  • Location: address, neighborhood, street, city, postal_code, state, country_code, lat, lng, plus_code
  • Business profile: category, categories, price_range
  • Contact: phone, website, website_domain
  • Reputation: rating, reviews_count
  • Availability: current_status, opening_hours, hours_status
  • Attributes: additional_info (service options, accessibility, amenities, payments and similar groups)
  • Context: search_query, search_position, result_id, source, platform, fetched_at

Google Maps Scraper input

Provide queries as an array of search strings, written the way you would type them into Google Maps: a business type plus a place works best ("dentist Rotterdam", "coffee shops amsterdam"). The actor processes the queries in order, keeps repeated queries, and records the corresponding search_query on every result. Empty strings are ignored. At least one non-empty query is required. The standard maximum is 120 places per query, rather than a combined limit across the entire run.

The following input was used for an actual run:

{
"queries": [
"plumbers Austin TX"
],
"max_results_per_query": 120,
"hl": "en",
"gl": "us",
"use_cookies": true,
"use_proxy": false
}
Input fieldDefaultMeaning
queriesRequiredOrdered list of searches
max_results_per_query120Maximum places per query; valid range 1–400
hlenLanguage of categories, status, weekly hours and attributes
glusResult locale
use_cookiestrueUse available anonymous Google sessions
use_proxyfalseRetained legacy access option

Increasing the maximum requests more places, but does not guarantee that Google has that many matches. A real search for "bakkerij Utrecht" with the maximum set to 400 returned 150 places. To cover a larger area, use distinct queries for the neighborhoods or towns you actually need. Results remain associated with their individual query even when several queries find the same business. You can deduplicate your exported data with place_id or fid when your workflow needs a single record per business.

Output

The run above returned 120 plumbers. This is the first actual result, unchanged. Its status and weekly hours describe the moment of collection, so a later run can legitimately show different values.

{
"search_position": 1,
"name": "Reliant Plumbing - Austin",
"fid": "0x8644cbf98cf77c3b:0xd9fd1d041b132575",
"place_id": "ChIJO3z3jPnLRIYRdSUTGwQd_dk",
"kgmid": "/g/11h_ftppjt",
"address": "Reliant Plumbing - Austin, 12111 Menchaca Rd, Austin, TX 78748",
"neighborhood": null,
"street": "12111 Menchaca Rd",
"city": "Austin",
"postal_code": "78748",
"state": "Texas",
"country_code": "US",
"lat": 30.1421389,
"lng": -97.8326841,
"category": "Plumber",
"categories": [
"Plumber"
],
"rating": 4.7,
"reviews_count": 1679,
"price_range": null,
"phone": "(512) 675-4220",
"website": "https://reliantplumbing.com/plumbing-projects-austin/?utm_source=google&utm_medium=website&utm_campaign=sagbp&utm_id=southaustin-GBP",
"website_domain": "reliantplumbing.com",
"plus_code": null,
"hours_status": null,
"current_status": "Open 24 hours",
"opening_hours": [
{
"day": "Friday",
"hours": "Open 24 hours"
},
{
"day": "Saturday",
"hours": "Open 24 hours"
},
{
"day": "Sunday",
"hours": "Open 24 hours"
},
{
"day": "Monday",
"hours": "Open 24 hours"
},
{
"day": "Tuesday",
"hours": "Open 24 hours"
},
{
"day": "Wednesday",
"hours": "Open 24 hours"
},
{
"day": "Thursday",
"hours": "Open 24 hours"
}
],
"additional_info": {},
"search_query": "plumbers Austin TX",
"result_id": "0:1",
"source": "google-maps-scraper",
"platform": "google_maps",
"fetched_at": "2026-10-02T11:12:27.301Z"
}

rating is numeric when available; reviews_count is an integer when available. Coordinates are numeric lat and lng. Categories remain a primary category and the complete available categories array. Fields that Google does not supply remain null. opening_hours is always a list of objects with day and hours, even when the list is empty. additional_info is always an object, with groups of boolean attributes; it is empty when Google lists no attributes, as in the row above.

Group labels and attribute labels follow the selected language, and some searches expose fewer groups than others. With hl set to nl, the first result for "bakkerij Utrecht" came back with Dutch labels:

{
"name": "De Bakkert in Oost",
"category": "Bakkerij",
"current_status": "Geopend ⋅ Sluit om 14:30",
"additional_info": {
"Toegankelijkheid": [
{
"Rolstoeltoegankelijke ingang": true
}
]
}
}

The legacy fields price_range, plus_code and hours_status remain present. They were null throughout the migration baselines, so do not rely on those fields being populated. Use current_status and opening_hours for availability information. The fields source, platform, fetched_at and result_id identify the product, collection time and individual occurrence within a query.

The actor also writes a summary key-value record with itemCount and errorCount. Query failures appear in an errors record when there are errors. The OUTPUT record reports delivered results and charging. These records complement the dataset; exported business rows remain in the dataset itself.

Use cases

  • Lead generation: collect phone numbers and websites of every roofer, dentist or restaurant in the towns you sell to, then load them into your CRM.
  • Local market mapping: count competitors per neighborhood, plot them with lat and lng, and compare ratings and review counts.
  • Directory and listing upkeep: refresh addresses, opening hours and categories for a business directory on a schedule.
  • Location research: check which categories are missing in an area before opening a new branch.

Check missing values before filtering: a null rating is unavailable information and should not automatically be interpreted as a poor rating. Preserve search_query when combining exported files so that you can explain why each listing was collected.

How this Google Maps scraper compares

Google Maps scrapers in the Apify Store range from all-in-one crawlers with reviews, photos and email enrichment to lean place extractors. This actor is deliberately lean:

This actorTypical all-in-one Google Maps scraper
Price modelOne event per delivered placeSeveral events: place, details, contacts, filters, reviews, images
Actor start feeNoneOften a small fee per run
Phone, website, hours, coordinatesIncluded in the place priceSometimes a separate details event
Reviews, photos, emails from websitesNot collectedAvailable as paid add-ons

If you need the business list itself, at a predictable price per row, this actor fits. If you need review text or photos, combine it with a dedicated tool, keyed on place_id.

Pricing

The established pay-per-event price is $0.0025 per delivered place, or $2.50 per 1,000 places. There is no actor-start event in this price model. An empty result set incurs no place charge. Results are delivered before their place event is charged, and a failed query does not add a place charge for data it did not return.

Users without a paid Apify plan receive at most ten places per run. Their delivered slice also determines the number of charged place events. Paid users retain their selected maximum per query. Apify manages your account usage allowance and displays the applicable actor price before a run starts.

Limits and error handling

Google controls the available results and their ordering. The maximum is a request limit, not a promise of complete city coverage. Opening hours, ratings, review counts and business information can change between runs. Duplicate businesses across queries are retained intentionally. Empty searches succeed without adding an errors record. A failed search records its query and allows later queries to continue.

FAQ

Can I keep my existing saved input?

Yes. The six existing input names and their defaults remain supported. Saved tasks using those fields continue to request the same type of business data, and existing dataset columns remain available.

Is this Google Maps scraper free?

Not entirely. Each delivered place costs $0.0025. Users without a paid Apify plan can run it and receive up to ten places per run, which is enough to check the output before you scale up. An empty search costs nothing.

Does this actor collect website email addresses or photographs?

This actor collects the structured business fields described above. It does not crawl linked websites for email addresses and does not return photograph records. Use the returned website and place identifiers with a separate workflow if you need those sources.

Why can a field be null or a list be empty?

Google does not supply every detail for every business. A missing phone, website, rating or schedule stays missing. The actor preserves the field and its expected JSON type so that downstream code can handle absence consistently.

What happens when one query returns nothing?

A query with no matches contributes zero rows and zero place events. Other queries in the same input still run. Input that contains only empty strings also finishes without business rows and records the established bad_input error.

Can I call it from my own code?

Yes. Start a run through the Apify API or one of the Apify client libraries with the same input JSON, then read the dataset items. The row format is the same as in the console, so the example above is what your code receives.