# Google Local Scraper - Businesses, Ratings & Reviews Count (`scrapesage/google-local-scraper`) Actor

Scrape Google local business results (the local pack) by search: name, rating, review count, category, address, hours, plus phone, website, booking link, description, social profiles and Google Maps id from each knowledge panel. 40+ countries. Independent tool, not affiliated with Google LLC.

- **URL**: https://apify.com/scrapesage/google-local-scraper.md
- **Developed by:** [Scrape Sage](https://apify.com/scrapesage) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.65 / 1,000 business listeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Google Local Scraper - Businesses, Ratings & Reviews Count

> **Disclaimer:** This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Google LLC or any of its subsidiaries. All trademarks mentioned are the property of their respective owners. "Google Local results" is referenced only to describe the publicly available website this Actor collects data from.

Search Google's local business results - the "local pack" / Places tab a searcher sees for `dentist in denver co` - and get every listing as a clean row: name, star rating, **review count**, category, address, opening status and the featured review. Turn on details and each row also carries phone, website, booking link, full address, the business's own description, highlights, social profiles, Google Maps id (CID) and review snippets from its knowledge panel. 20 businesses per page, several pages per search, 40+ country editions. No login, no browser, no API key.

### What you get

| Field | What it holds |
|---|---|
| `name`, `category`, `address`, `hoursText`, `openStatus`, `opensText` | The listing as Google shows it |
| `rating`, `reviewCount`, `ratingText` | Star rating and the number of Google reviews - the count most scrapers cannot get without a browser |
| `reviewSnippet`, `reviewSnippets` | The featured review on the card plus up to five quotes from the knowledge panel |
| `phone`, `phoneE164`, `website`, `bookingUrl`, `appointmentsProvider` | Contact and booking data from the knowledge panel (details on) |
| `fullAddress`, `city`, `locatedIn`, `description`, `highlights`, `servicesLink`, `socialProfiles` | Everything else the panel publishes |
| `kgId`, `cid`, `fid`, `mapsUrl`, `googleSearchUrl` | Google's knowledge-graph id, Maps CID and feature id, and direct links to the business on Google Maps and Google Search |
| `isSponsored`, `position`, `page`, `searchQuery` | Ad flag, rank and how the row was found |

### Why this scraper

- **Review counts and ratings without a browser.** The local pack prints them on every card; this actor reads them straight from the page, so a 100-business list costs cents and takes seconds.
- **Contact data in the same run.** With details on, every business is enriched from its own Google knowledge panel: phone, website, booking link, description, highlights, social profiles and the Maps CID - the fields a lead list actually needs.
- **Rank as Google ranks it.** Rows carry the position Google gave them for that query, page by page, so you can track local rankings per search and city.
- **Honest about ads.** Sponsored listings are flagged and skipped by default; turn them on when you want to see who is paying for the top slot.
- **International.** Pick the country edition and interface language; the query can be in any language.

### Use cases

- **Local lead generation** - dentists, plumbers, agencies, restaurants in a city with phone, website and booking link.
- **Local SEO and rank tracking** - who ranks in the pack for a keyword, with rating and review count, per city and per run.
- **Reputation monitoring** - ratings, review counts and review snippets for your locations and competitors, on a schedule.
- **Market mapping** - density of a business type across areas, with ratings and highlights.
- **Data enrichment** - Google Maps CID, website and phone for a list of business names.

### How to use

1. Enter one or more local searches - `dentist in denver co`, `coffee shop in shoreditch london`, `Zahnarzt in Berlin Mitte`.
2. Keep **Add phone, website & details** on for a full record, or turn it off for a cheap ranking snapshot.
3. Optionally set a minimum rating / review count, the country edition and language, and **Maximum businesses**. Run; rows land in the dataset within seconds.

You can also paste Google local-results URLs (`google.com/search?q=...&tbm=lcl`) into **Google Local URLs**, or import a list of them from a text file or Google Sheet.

### Input

```json
{
    "queries": ["dentist in denver co", "dentist in boulder co"],
    "countryCode": "us",
    "language": "en",
    "enrichWithDetails": true,
    "minRating": "4",
    "maxResults": 100
}
```

Every field is optional. With no input at all the actor runs a small sample search so you can see the output shape.

### Output example

```json
{
    "type": "place",
    "name": "OG Dental",
    "rating": 4.9,
    "reviewCount": 559,
    "category": "Dentist",
    "address": "4402 Umatilla St",
    "hoursText": "Closed · Opens 8 AM Tue",
    "openStatus": "Closed",
    "reviewSnippet": "Dr. Grady filled my tooth in less than 30 mins while I watched Netflix!",
    "kgId": "/g/11gsltks9j",
    "isSponsored": false,
    "phone": "(720) 679-8577",
    "phoneE164": "+17206798577",
    "website": "https://www.ogdentaldenver.com/?utm_campaign=gmb",
    "bookingUrl": "https://flexbook.me/ogdental?...",
    "fullAddress": "4402 Umatilla St, Denver, CO 80211",
    "city": "Denver, Colorado",
    "description": "Welcome to OG Dental! You can expect CAREFUL, COMFORTABLE, AND CONVENIENT DENTAL CARE IN DENVER ...",
    "highlights": ["Payment plans", "Emergency services", "Sedation dentistry"],
    "socialProfiles": [{ "network": "YouTube", "url": "..." }, { "network": "Instagram", "url": "..." }],
    "cid": "4858428693489532659",
    "mapsUrl": "https://www.google.com/maps?cid=4858428693489532659",
    "reviewSnippets": ["Excellent staff, service, and experience overall.", "Beautiful facility, they provide excellent services and customer service."],
    "detailsFetched": true,
    "searchQuery": "dentist in denver co",
    "position": 1,
    "page": 1,
    "countryCode": "us",
    "language": "en",
    "scrapedAt": "2026-09-06T06:10:01.981Z"
}
```

### Reliability - read this before you buy

- **20 businesses per page, usually 3-10 pages per search.** The actor walks pages until Google stops; use several queries (neighbourhoods, business types) for more.
- **Details cost one extra Google page per business** and are charged as a separate event only when the panel was actually read. Businesses without a knowledge panel (rare) keep the listing fields only.
- **Some fields depend on the business.** Hours, website, phone, description, highlights, booking links and social profiles exist only where the business published them; those fields are `null` or empty when Google does not show them - nothing is invented.
- **Sponsored listings** appear on some pages; they are flagged and skipped unless you turn them on.
- **Hotels are not covered.** Google routes hotel, motel and hostel searches to its Hotels vertical, which has no local-results cards; the run says so and bills nothing for businesses. Use a hotel scraper for lodging.
- **Service-area businesses show no street address on the card.** Plumbers, electricians, cleaners and similar trades that come to you are listed by Google without a street line (15 of 20 Austin plumbers on our test). With details on, the knowledge panel supplies the full address; without details the `address` field stays empty for those rows.
- **Every run ends with a plain-language status message** that says what happened and, when a run returns nothing, which input to change.

### How much does it cost to scrape Google Local results?

This Actor uses Apify's **pay-per-event** pricing: you are charged only for the results it delivers, with no monthly rental and no start fee. The events it can charge are:

- **Business listed** - Charged once per business written to your dataset from Google's local results - name, rating, review count, category, address, hours, featured review and Google id. Duplicates, sponsored listings you excluded and businesses that fail your rating/review filters are never charged.
- **Business details** - Charged once per business whose Google knowledge panel was read and merged into the row - phone, website, booking link, full address, description, highlights, social profiles, Google Maps id (CID) and review snippets. Charged only when the panel was actually fetched.
- **Google local results page** - Charged once per Google local-results page fetched (20 businesses each). A search that returns no businesses is charged as one page.

The current price of each event is shown on the **Pricing** tab of this page. Set a maximum total charge on the run if you want a hard cap on spend, and use the input limits to control how much the Actor fetches.

### Automate & schedule

Run this Actor on autopilot and pull results into your own stack:

- **[Apify API](https://docs.apify.com/api/v2)** - start runs, fetch datasets and manage schedules over REST.
- **[apify-client for JavaScript](https://docs.apify.com/api/client/js/)** and **[apify-client for Python](https://docs.apify.com/api/client/python/)** - official SDKs.
- **[Schedules](https://docs.apify.com/platform/schedules)** - run it hourly, daily or weekly and keep your dataset current.
- **[Webhooks](https://docs.apify.com/platform/integrations/webhooks)** - trigger downstream actions (CRM import, Slack alert, email sequence) the moment a run finishes.

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

const client = new ApifyClient({ token: 'MY_APIFY_TOKEN' });

const run = await client.actor('scrapesage/google-local-scraper').call({
    // your input - see the Input section above
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} records`);
```

### Integrate with any app

Connect the dataset to thousands of apps - no code required:

- **[Make](https://docs.apify.com/platform/integrations/make)** - multi-step automation scenarios.
- **[Zapier](https://docs.apify.com/platform/integrations/zapier)** - push new records straight into your CRM or spreadsheet.
- **[Slack](https://docs.apify.com/platform/integrations/slack)** - get notified when a scheduled run finds something new.
- **[Google Drive / Sheets](https://docs.apify.com/platform/integrations/drive)** - auto-export every run to a spreadsheet.
- **[Airbyte](https://docs.apify.com/platform/integrations/airbyte)** - pipe results into your data warehouse.
- **[GitHub](https://docs.apify.com/platform/integrations/github)** - trigger runs from commits or releases.

### Use with AI assistants (MCP)

The output is clean, LLM-ready JSON. You can call this Actor from Claude, ChatGPT or any agent framework through the **[Apify MCP server](https://docs.apify.com/platform/integrations/mcp)** - describe the data you need and let the assistant run this Actor for you.

### Agent-ready: autonomous payments (x402 & Skyfire)

This actor is **agent-ready** — AI agents can discover it, run it, and **pay for it autonomously**, with no Apify account and no human in the loop. It uses [pay-per-event](https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event) pricing and [limited permissions](https://docs.apify.com/platform/actors/development/permissions), so it qualifies for Apify's agentic-payment standards:

- **[x402](https://docs.apify.com/platform/integrations/x402)** — an open, HTTP-native payment protocol. Agents pay per run in USDC on the Base network directly through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) — no account, no API key.
- **[Skyfire](https://docs.apify.com/platform/integrations/skyfire)** — agent-to-service payments for fully autonomous AI-agent workflows.

Building an AI agent, MCP tool, or autonomous data pipeline? This scraper is ready to plug in and pay as it goes.

### Tips

- Put the place in the query (`... in denver co`) or in **Location**; a business type plus a city or neighbourhood gives the most complete pack.
- For rank tracking, turn details off, set a fixed `maxPagesPerQuery`, and schedule the same queries daily; `position` and `page` give you the movement.
- `minReviews` is the quickest way to a list of established businesses; `minRating` for the best-rated.
- Use the matching country edition: `gb` for London, `de` for Berlin, `au` for Sydney.

### FAQ

**Is this Google Maps?** It is Google Search's local results (the same businesses, ranked as a web searcher sees them) plus each business's Google knowledge panel. The `mapsUrl` opens the business on Google Maps.

**Do I get reviews?** You get the rating, the review count, the featured review on the card and up to five review quotes from the knowledge panel - not the full review list.

**Does it log in or use cookies?** No. It reads Google's public results pages through Apify's Google search proxy.

**What happens on a Google challenge page or a network error?** The page is retried; if it still fails the run continues with the other searches and the status message names the failure. A run never fails hard on a transient block.

### Disclaimer

**This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Google LLC or any of its subsidiaries. All trademarks mentioned are the property of their respective owners.**

"Google Local results" and any related marks are the property of their respective owners and are used here only in a descriptive, nominative sense - to identify the publicly accessible website from which this Actor collects data. This Actor is not an official Google Local results product, is not authorised or certified by Google LLC, and does not distribute Google Local results software. It collects only publicly available information; you are responsible for ensuring your use of that data complies with applicable laws, regulations and the terms of the source website.

### Need help?

Open an issue on the Actor's **Issues** tab, or visit the [Apify help center](https://help.apify.com/). Feature requests are welcome - this Actor is actively maintained.

# Actor input Schema

## `queries` (type: `array`):

One local search per line, as you would type it into Google - e.g. `dentist in denver co`, `italian restaurant near soho london`, `plumber austin tx`.

## `location` (type: `string`):

Optional city or area appended to every query as `... in <location>` when the query does not already name a place.

## `startUrls` (type: `array`):

Optional. Paste Google local-results URLs (google.com/search?q=...\&tbm=lcl). The query, country and language are read from each URL. Use the file/link option to import a list.

## `urlsFromFile` (type: `string`):

Optional. Either paste a block of Google local-results URLs (one per line) or a single link to a .txt/.csv file (or a Google Sheet share link) that lists them.

## `countryCode` (type: `string`):

Google country edition used for the search.

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

Interface language for the search (categories and hours come back in this language).

## `enrichWithDetails` (type: `boolean`):

For every listing, open the business's Google knowledge panel and add phone, website, booking link, full address, description, highlights, social profiles, Google Maps id (CID) and review snippets. One extra Google page per business.

## `minRating` (type: `string`):

Only keep businesses rated at least this many stars (businesses without a rating are dropped when set).

## `minReviews` (type: `integer`):

Only keep businesses with at least this many Google reviews.

## `includeSponsored` (type: `boolean`):

Keep the paid 'Sponsored' listings Google shows at the top of some local results (flagged with isSponsored). Off by default.

## `maxResults` (type: `integer`):

Stop after this many businesses across all queries. Google serves 20 per page and typically 3-10 pages per search.

## `maxPagesPerQuery` (type: `integer`):

How many result pages (20 businesses each) to read per query.

## `monitorMode` (type: `boolean`):

Remember every business seen in earlier runs and output only new ones. Pair with a Schedule to watch a search for newly listed businesses.

## `monitorStoreName` (type: `string`):

Key-value store that keeps the seen business ids (lowercase letters, numbers and dashes).

## `maxConcurrency` (type: `integer`):

How many Google pages are fetched at the same time (searches and knowledge panels).

## Actor input object example

```json
{
  "queries": [
    "dentist in denver co"
  ],
  "countryCode": "us",
  "language": "en",
  "enrichWithDetails": true,
  "minRating": "any",
  "includeSponsored": false,
  "maxResults": 60,
  "maxPagesPerQuery": 5,
  "monitorMode": false,
  "monitorStoreName": "google-local-monitor",
  "maxConcurrency": 4
}
```

# Actor output Schema

## `results` (type: `string`):

Every business collected in this run.

# 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 = {
    "queries": [
        "dentist in denver co"
    ],
    "maxResults": 60
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/google-local-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 = {
    "queries": ["dentist in denver co"],
    "maxResults": 60,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapesage/google-local-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 '{
  "queries": [
    "dentist in denver co"
  ],
  "maxResults": 60
}' |
apify call scrapesage/google-local-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapesage/google-local-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/fbuPwhJVqeuJWgW2Q/builds/tthhUvimb9Bo5HJ5h/openapi.json
