DRAFT tutorial. Not indexed by search engines. Not yet listed on the tutorials hub. Review + iterate in the Claude Code session, then merge the "Publish tutorial" PR to make it public.

How to Scrape Google Maps

Type a search query, click Run, and in about ten seconds you have a structured dataset with 30-plus fields per business: name, category, full address, phone, website, rating, review count, opening hours, GPS coordinates, price range, and more. No code, no browser automation, no proxy setup. The NanoScrape Google Maps Scraper handles everything on Apify's infrastructure.

Apify Console dataset view showing Google Maps scraper results with business names, addresses, phones, ratings and review counts in structured columns
What a finished run looks like: 30+ fields per place, ready to export as JSON, CSV, or Excel.
Difficulty: Beginner
Time: 5 minutes
Cost: $1 per 1,000 places (free tier covers ~5,000/month)
Tools: Apify Console (no code)
Open the actor on Apify → See pricing details

In this tutorial

  1. What you get
  2. Step 1: Create your Apify account
  3. Step 2: Set your search query
  4. Step 3: Run the scraper
  5. Step 4: Export your data
  6. Add emails, reviews, and more
  7. Automate with the API
  8. What it costs
  9. Common use cases
  10. FAQ

What you get

Every place the scraper returns comes with 30-plus structured fields. Here is an abbreviated example output (the actor's own documented example, showing the shape of a real result):

{
  "title": "Example Bistro",
  "category": "French restaurant",
  "address": "1 Example Street, 75000 Paris, France",
  "complete_address": {
    "street": "1 Example Street",
    "city": "Paris",
    "postal_code": "75000",
    "country": "France"
  },
  "phone": "+33 1 00 00 00 00",
  "website": "https://www.example.com/",
  "review_rating": 4.5,
  "review_count": 1823,
  "status": "OPERATIONAL",
  "price_range": "$$",
  "open_hours": {
    "Monday": ["12:00-14:30", "19:00-22:30"],
    "Friday": ["12:00-14:30", "19:00-23:00"]
  },
  "latitude": 48.8571,
  "longitude": 2.3007,
  "cid": "12345678901234567",
  "scraped_at": "2026-07-24T10:00:00.000Z"
}

Beyond the basics, you can opt in to reviews, popular-times histograms, email addresses, social profiles (Facebook, Instagram, LinkedIn, Twitter/X, TikTok, YouTube), SSL inspection, WHOIS data, tech stack detection, and AI-powered contact extraction. Every enrichment is billed separately only when you enable it.

30-plus fields are included in the base price. Popular times, GBP completeness score, chain detection, duplicate tagging, and reservation-platform parsing are all included. Reviews are the only add-on billed separately ($0.30 per 1,000 reviews when you set includeReviews: true).
STEP 1

Create your free Apify account

  1. Go to the Google Maps Scraper page on Apify.
  2. Click Try for free. Sign up with Google or email. It takes about a minute.
  3. You land in Apify Console with the actor's Input tab open and $5 of free credit ready to use.
NanoScrape Google Maps Scraper page on Apify Console with the Try for free button highlighted in orange
The actor page on Apify. Click Try for free to open the Input tab.
Already have an Apify account? Skip to Step 2. If you want to use an existing account that belongs to an organization, make sure you have Actor run permissions on that workspace.
STEP 2

Set your search query

The scraper's Input tab has two ways to define what to search. The simplest is searchStrings: an array of plain text queries, each one sent directly to Google Maps.

{
  "searchStrings": [
    "coffee shops in Berlin",
    "dentists in New York",
    "law firms in London"
  ],
  "maxResultsPerQuery": 20
}

A few tips that make a real difference:

Apify Console Input tab for the Google Maps Scraper showing the searchStrings field with example queries and maxResultsPerQuery set to 20
The Input tab. Paste your queries into searchStrings and set how many results you want per query.
Structured queries with a company_id: if you are enriching an existing list, use the queries array instead. Pass a company_id per query and the scraper copies it into every result row, making it easy to join back to your source data without matching on name or address.
STEP 3

Run the scraper

Click Save and Run at the bottom of the Input tab. You land on the run detail page. The Log tab streams progress in real time, and the Dataset tab populates as each query finishes.

Apify Console run detail page showing the live log with query progress and the dataset tab showing rows accumulating
The run detail page. Log tab shows progress; Dataset tab fills in as results arrive.

Speed depends on the number of queries and maxResultsPerQuery. A typical run of 3 queries at 20 results each finishes in 10 to 20 seconds. A run of 10 queries at 100 results each takes about two minutes.

If a run finishes but the dataset looks empty, click the Dataset tab and check that the view is not filtered. You can also open the Log tab and look for error lines. The most common causes are a search query that returns zero results (the location is misspelled or too specific) or a temporary proxy issue (re-running once usually clears it).

STEP 4

Export your data

Open the Dataset tab on the run detail page. Click Export at the top right. You can download as:

Apify Console Dataset tab with the Export button highlighted and a dropdown showing JSON, CSV, Excel and other format options
Click Export to download the dataset in the format that fits your workflow.

If you want to pull results into an automation tool like n8n, Make, or Zapier instead of downloading a file, skip to the API section below. Every dataset is also accessible by its URL from any Apify run, so you can poll it or pipe it directly into a downstream step.

Add emails, reviews, and more

The base scrape returns the 30-plus fields you saw above. These optional add-ons stack on top, each enabled by a single flag in the Input JSON.

Featured reviews

Set "includeReviews": true and each place gets a user_reviews array with author name, star rating, publication date, and review text. Sort options: most_relevant, newest, highest_rating, lowest_rating. To filter by date, add "reviewsNewerThan": "2026-01-01" and the scraper stops pulling once it passes that cutoff.

Reviews have a separate charge: $0.30 per 1,000 reviews. They are not included in the base $1 per 1,000 places. If you enable includeReviews and scrape 500 places at 10 reviews each, that is 5,000 reviews, billed at $0.30 extra on top of the base place charge.

Popular times histogram

Set "includePopularTimes": true and each result gets a popular_times object with visitor-traffic scores (0 to 100) broken down by weekday and hour. Adds about 1.5 seconds per place. Included in the base $1 per 1,000 place price.

"popular_times": {
  "Monday": { "9": 38, "10": 52, "11": 70, "12": 81, "13": 79 },
  "Saturday": { "10": 60, "11": 88, "12": 95, "13": 90 }
}

Email addresses and social profiles

Set "enableEmailExtraction": true and the scraper visits every business website it found and pulls out email addresses, phone numbers, and social profile URLs (LinkedIn, Facebook, Instagram, Twitter/X, TikTok, YouTube) using a regex extractor. No LLM key needed.

AI-powered contact extraction

Set "enableContactExtraction": true and provide a geminiApiKey (free tier available at Google AI Studio). The scraper visits each business website and extracts structured contacts: name, position, email, phone, department. Results merge into the same dataset row as the Maps data.

{
  "searchStrings": ["IT companies in Munich"],
  "maxResultsPerQuery": 20,
  "enableContactExtraction": true,
  "enableEmailExtraction": true,
  "geminiApiKey": "your-gemini-api-key",
  "waitForAddOns": true
}
All add-on results merge into one row per business when waitForAddOns: true (the default). You get one clean dataset with everything in it, no join step needed. If you set waitForAddOns: false, add-ons run in the background and write to separate datasets that you join yourself.

Automate with the API

Every actor on Apify can be called from your code or an automation platform. The simplest path is a synchronous HTTP call: POST your input JSON and the API blocks until the run completes, then returns the dataset.

curl -s -X POST \
  "https://api.apify.com/v2/acts/santamaria-automations~google-maps-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searchStrings": ["plumbers in Chicago"],
    "maxResultsPerQuery": 50
  }'

The response is a JSON array of place objects, ready to pipe into your database, spreadsheet, or downstream API. Get your personal API token from Apify Console › Settings › Integrations.

For long-running jobs (thousands of places, many queries), use the async variant instead: POST to start a run, get back a runId, then poll /v2/actor-runs/{runId}/dataset/items until the run status is SUCCEEDED. The actor README has code examples in JavaScript, Python, and cURL.

Use via n8n, Make, or Zapier

If you prefer a no-code automation platform, all three support Apify natively. For n8n specifically, there is a step-by-step tutorial that walks you through connecting the scraper to a Google Sheet: How to Scrape Google Maps with n8n.

Connect to an AI agent via MCP

The scraper also ships an MCP server. Paste this URL into your MCP client (Claude Desktop, Cursor, VS Code, or any LangChain / LlamaIndex agent):

https://mcp.apify.com?tools=santamaria-automations/google-maps-scraper

Once connected, you can prompt the agent directly: "Find pediatric dentists in Zurich and put them in a table." The agent discovers the input schema automatically and runs the actor on your behalf.

What it costs

A practical estimate: scraping 500 places across ten queries takes about 2 minutes and costs $0.50. Adding reviews at 10 per place adds another $0.15. Contact extraction via the AI add-on adds a small per-place cost on top, depending on which LLM provider you use (Gemini's free tier handles most jobs without a paid plan).

Common use cases

Lead generation

Search for businesses in a specific category and city, add email extraction, and export to your CRM or cold-email tool. Filter by review_count, review_rating, or status: OPERATIONAL to focus on active businesses.

Market research

Map every competitor in a region. The local_rank field (automatic when two or more places share the same category and city) shows each place's position in its cohort by review count, plus how many reviews separate it from position 3.

SEO and reputation monitoring

Pull reviews on a schedule with reviewsNewerThan set to last week's date. If the review_intel_math block (automatic when includeReviews is on) shows rating_trend: "declining", flag the account for review.

Data enrichment for existing lists

Use the queries array instead of searchStrings. Pass your internal company_id alongside each query. The scraper copies it into every result row, making it trivial to join the enriched data back to your source list without matching on name or address.

FAQ

Do I need to write any code to scrape Google Maps?

No. The Apify Console gives you a form-based input editor. Type your search queries, click Save and Run, and download the results. Code is only needed if you want to call the actor from an automation pipeline or your own application.

How many results can I get per query?

Up to 120 per single query, which is Google Maps' page limit for one search. For wider coverage, split your search by neighborhood, sub-category, or city district and run each as a separate search string. For example, instead of "restaurants in London", try "restaurants in Shoreditch", "restaurants in Camden", and "restaurants in Notting Hill".

Are reviews included in the base price?

No. Reviews are billed separately at $0.30 per 1,000 reviews, only when you explicitly set includeReviews: true. Everything else, including popular times, GPS coordinates, opening hours, photo URLs, price range, and category data, is included in the base $1 per 1,000 places.

Can I scrape businesses worldwide or only in the US?

The scraper works on any country and language Google Maps covers. Include the country or city in your search string and set the language parameter to the appropriate ISO 639-1 code (de for German, fr for French, ja for Japanese, etc.) to get localized results.

How fresh is the data?

Every scrape hits the live Google Maps API at run time. There is no cached data or stored snapshot. Whatever Google shows at the moment you run the actor is what you get.

Can I get email addresses along with the Google Maps data?

Yes. Enable enableEmailExtraction: true for a regex-based extractor that pulls emails, phone numbers, and social profile URLs from each business's website, with no API key required. For structured contacts (name, position, email), also enable enableContactExtraction: true and provide a Gemini or Groq API key. Results merge into the same dataset row as the Maps data.

Is scraping Google Maps legal?

Scraping publicly visible data from websites is generally allowed in most jurisdictions under the Computer Fraud and Abuse Act (US) and similar laws. The hiQ Labs v. LinkedIn ruling confirmed that scraping public web data is not unauthorized access. That said, GDPR and local privacy laws apply to any personal data you collect and store. Consult legal counsel for your specific situation.

Can I skip places I have already scraped on repeat runs?

Yes. Every Google Maps place has a stable cid field that does not change even if the business renames or moves. Pass an array of CIDs in excludeCids and the scraper skips them. A common pattern in automated workflows: read the CID column from your previous export, pass the array back in, and only new places land in the output.

Related resources

Open the actor on Apify → See all tutorials