# Google Maps Places Scraper (`codingfrontend/google-maps-places-scraper`) Actor

Scrape Google Maps places data including business name, address, phone, website, ratings, reviews, and more. Extract leads and business information from Google Maps search results.

- **URL**: https://apify.com/codingfrontend/google-maps-places-scraper.md
- **Developed by:** [Coding Frontned](https://apify.com/codingfrontend) (community)
- **Categories:** Developer tools, Lead generation, Automation
- **Features:** Limited permissions
- **Stats:** 337 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.99 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Google Maps Places Scraper

Extract source-backed business places from public Google Maps search pages. The Actor captures structured Maps response data and visible business-specific Maps links, then applies optional rating, category, contact, and closure filters.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `searchTerms` | string\[] | required | 1–50 unique Google Maps searches |
| `searchStringsArray` | string\[] | — | Legacy alias for `searchTerms` |
| `locationQuery` | string | blank | Optional location appended to every term |
| `maxPlaces` | integer | `20` | Exact per-search cap, 1–500 |
| `maxCrawledPlacesPerSearch` | integer | — | Legacy alias for `maxPlaces` |
| `minimumRating` | number | blank | Source-backed rating threshold from 1 to 5 |
| `placeMinimumStars` | string | blank | Legacy alias for `minimumRating` |
| `closedPlacesFilter` | string | `all` | `all`, `skipClosed`, or `onlyClosed` |
| `onlyWithWebsite` | boolean | `false` | Only scrape places that have a listed official website |
| `onlyWithPhone` | boolean | `false` | Only scrape places that have a contact telephone number |
| `onlyOpenNow` | boolean | `false` | Only scrape places that are currently reported as open |
| `categoryFilter` | string\[] | blank | Filter places by category keywords (e.g. `["pizza", "italian"]`) |
| `maximumPhotos` | integer | `10` | Maximum photo URLs to extract per place (0–50) |
| `language` / `country` | string | `en` / `US` | Maps locale and country |
| `fingerprintProfile` | string | `chrome-windows` | Retained browser compatibility input; not written to dataset rows |
| `proxySessionId` / `proxyConfiguration` | string / object | blank / Residential | Optional proxy settings for live public-page access |
| `fixtureFile` | string | blank | Local-only relative `.html`/`.htm` fixture for deterministic QA |

### Output

Normal rows contain rich business details and source provenance:

- **Identity**: `recordId`, `businessName`, `name` (compatibility alias), `placeId`, `cid`, `entityId`
- **Classification**: `category`, `categories`
- **Location**: `address`, `street`, `city`, `state`, `postalCode`, `countryCode`, `countryName`, `latitude`, `longitude`, `timezone`, `plusCode`
- **Contact & Web**: `phone`, `website`, `domain`, `email`
- **Rating & Reviews**: `rating`, `reviewCount`, `priceLevel`
- **Status & Schedule**: `openNow`, `openingStatus`, `openingHours` (7-day schedule), `permanentlyClosed`, `temporarilyClosed`
- **Media**: `thumbnailUrl`, `photoUrls`, `photoCount`
- **Actions & Details**: `description`, `menuUrl`, `orderOnlineUrl`, `reservationUrl`
- **Provenance**: `mapsUrl`, `sourceUrl`, `searchTerm`, `searchTermIndex`, `resultRank`, `position`, `scrapedAt`

When Google shows a CAPTCHA, consent page, traffic block, or the run cannot produce usable places, the Actor writes a diagnostic row with exactly `url`, `error`, `errorCode`, and `scrapedAt`. Operational status, counters, source mode, proxy mode, and profile name are stored in `OUTPUT` and `RUN_HEALTH` in the default key-value store.

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

### Access and responsible use

Use public Google Maps pages in accordance with Google terms, robots guidance, applicable law, and reasonable rate limits. The Actor does not log in, solve CAPTCHAs, bypass WAFs, or evade access controls. A source boundary is recorded and the run fails closed.

### Local development

```sh
npm install
npm test
npm run validate
```

Deterministic fixture run:

```sh
node src/main.js
```

The fixture is synthetic and local-only. Apify authentication is required only for cloud Console/API operations.

# Changelog

This Actor's version history is a separate document: https://apify.com/codingfrontend/google-maps-places-scraper/changelog.md

# Actor input Schema

## `searchTerms` (type: `array`):

Unique Google Maps searches.

## `searchStringsArray` (type: `array`):

Compatibility alias for searchTerms.

## `locationQuery` (type: `string`):

Optional location appended to each query.

## `maxPlaces` (type: `integer`):

Exact per-search result cap.

## `maxCrawledPlacesPerSearch` (type: `integer`):

Compatibility alias for maxPlaces.

## `minimumRating` (type: `number`):

Only source-backed ratings at or above this value are emitted.

## `placeMinimumStars` (type: `string`):

Compatibility alias for minimumRating.

## `minReviewCount` (type: `integer`):

Filter out businesses with fewer than this number of reviews.

## `closedPlacesFilter` (type: `string`):

Filters only explicit source-backed permanent-closure facts.

## `onlyWithWebsite` (type: `boolean`):

Only extract places that have an official website listed.

## `onlyWithPhone` (type: `boolean`):

Only extract places that have a contact phone number listed.

## `onlyOpenNow` (type: `boolean`):

Only extract places that are currently open according to Google Maps.

## `onlyClaimed` (type: `boolean`):

Only extract businesses that are claimed/verified by an owner on Google Business Profile.

## `onlyWithSocialProfiles` (type: `boolean`):

Only extract businesses that have at least one social media link (Facebook, Instagram, Twitter/X, LinkedIn, TikTok, YouTube).

## `categoryFilter` (type: `array`):

Filter results by category keywords (e.g. \['italian restaurant', 'pizza']).

## `priceRangeFilter` (type: `array`):

Filter results by price tier symbols (e.g. \['$', '$$']).

## `extractAttributes` (type: `boolean`):

Include rich structured amenities (accessibility, service options, offerings, payments, etc.).

## `extractServiceOptions` (type: `boolean`):

Include structured dining and service option flags (dine-in, takeout, delivery, curbside pickup, outdoor seating).

## `extractSocialProfiles` (type: `boolean`):

Include structured social media profile URLs discovered for each business.

## `extractPopularTimes` (type: `boolean`):

Include the 7-day hourly busy percentage histogram and wait time details.

## `scrapePlaceDetails` (type: `boolean`):

Opens each place card in the search feed to capture full details (website, description, owner, attributes, popular times, social profiles). Enabled by default.

## `maximumPhotos` (type: `integer`):

Maximum number of photo URLs to collect per business place (0 to 50).

## `language` (type: `string`):

Maps language code.

## `country` (type: `string`):

Two-letter Maps country code.

## `fingerprintProfile` (type: `string`):

Consistent Chrome desktop settings; dataset rows store business data, not fingerprint telemetry.

## `proxySessionId` (type: `string`):

Optional fixed safe proxy session ID.

## `proxyConfiguration` (type: `object`):

Apify Residential is recommended for cloud reliability.

## `fixtureFile` (type: `string`):

Optional relative .html/.htm path inside the Actor directory for deterministic local QA. It is never used as a cloud source.

## Actor input object example

```json
{
  "maxPlaces": 20,
  "minReviewCount": 0,
  "closedPlacesFilter": "all",
  "onlyWithWebsite": false,
  "onlyWithPhone": false,
  "onlyOpenNow": false,
  "onlyClaimed": false,
  "onlyWithSocialProfiles": false,
  "extractAttributes": true,
  "extractServiceOptions": true,
  "extractSocialProfiles": true,
  "extractPopularTimes": true,
  "scrapePlaceDetails": true,
  "maximumPhotos": 10,
  "language": "en",
  "country": "US",
  "fingerprintProfile": "chrome-windows",
  "proxySessionId": "",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `keyValueStore` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("codingfrontend/google-maps-places-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("codingfrontend/google-maps-places-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call codingfrontend/google-maps-places-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,codingfrontend/google-maps-places-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/MTLBtoOalaWc2tdQp/builds/avLPqPjC9hlWYlPuY/openapi.json
