Prompts to create a Google Maps lead scraper
These prompts are based on the How a Google Maps scraper generated $67,500 in pipeline for a demand gen specialist story featuring Bharatt Arorah of Claygen, published on the AI Lab by ActiveCampaign.

Get the prompt template
How to use these prompts
These are ready-to-use prompts pulled from the workflow Bharatt Arorah, outbound engineer and owner of Claygen, used to build a Google Maps lead scraper that generated $67,500 in pipeline. Copy, paste, and swap in details where you see [BRACKETS]. Run them in order—each one builds on the code from the last. Every AI tool behaves a little differently, so treat what comes back as a starting point: review the output and refine from there.
Prompt 1: Test your API connection before building anything
Best for: Confirming your RapidAPI key and coordinate file both work, before you spend a big prompt (and tokens) building the full scraper.
Use with: Claude Code desktop app (needs terminal and file access)
API connection test prompt
Create a file called test_api.py that makes exactly ONE request to the Maps Data API to confirm my setup works without wasting my quota. It should: load RAPIDAPI_KEY and RAPIDAPI_HOST from .env; read the first coordinate from [COORDINATES_FILE]; call https://maps-data.p.rapidapi.com/searchmaps.php with query=[TEST_KEYWORD], limit=1, country=us, lang=en, offset=0, zoom=13, and that coordinate’s lat/lng; send the key and host as the x‑rapidapi-key and x‑rapidapi-host headers; print the HTTP status and the first business name. If the status is 401/403, tell me my key is wrong; if 429, tell me I’ve hit my quota.
Variables to fill in:
- [COORDINATES_FILE]—the coordinates CSV in your project folder (e.g. 5km_deduped_coords.csv if you’re using the GeoNames-sourced file from the source workflow)
- [TEST_KEYWORD]—any simple business type to sanity-check the connection, e.g. restaurant
What to expect: An HTTP 200 status and a real business name printed to the terminal. If you get a 401/403 or 429 instead, fix your key or wait out the quota before moving on—don’t run a full scrape until this passes.
Prompt 2: Build the basic scraper
Best for: Turning a coordinate file and an API key into a working command-line tool that exports a clean, deduplicated CSV of local businesses.
Use with: Claude Code desktop app
Basic scraper
You are helping me build the first working version of a Google Maps lead scraper for local business prospecting. Create a Python command-line tool that takes a business search term, searches across a coordinate grid, calls the RapidAPI Maps Data API, deduplicates the results, and exports a clean CSV.
Coordinate file: [COORDINATES_FILE] in the project folder (~27,600 US rows). Columns: country code, postal code, City, State, State code, admin name2, admin code2, latitude, longitude. Inspect the file and match the columns tolerantly (case-insensitive).
API contract (use exactly this):
- Method/URL: GET https://maps-data.p.rapidapi.com/searchmaps.php
- Headers: x‑rapidapi-key (read from env var RAPIDAPI_KEY) and x‑rapidapi-host (read from env var RAPIDAPI_HOST, default maps-data.p.rapidapi.com).
- Query params: query (the keyword), lat, lng, and defaults limit=20, country=us, lang=en, offset=0, zoom=13. Put these defaults in one CONFIG block at the top so I can edit them.
- Response JSON shape: {“data”: [ { …business… }, … ]}. Each business object has these fields (capture all that are present): business_id, name, full_address, phone_number, website, rating, review_count, timezone, place_link, types (a list — join into a “category” column), price_level, and state (an open/closed text — output it as “open_status” so it doesn’t clash with the US state).
Do not hardcode secrets. Read RAPIDAPI_KEY from the environment (it’s in .env). Create scraper.py and requirements.txt.
CLI flow: ask (1) the business keyword; (2) location scope — Entire US / specific state(s) / specific city/cities; (3) if state scope, accept comma-separated state codes like TX,FL,NY; (4) if city scope, accept comma-separated city names. Filter the coordinate CSV to the chosen scope.
Use 30 parallel threads, process coordinates in batches of 100, and handle: timeouts, HTTP errors, rate limits (429) with exponential backoff, empty/malformed responses, failed coordinates after max retries, and Ctrl‑C without losing collected results.
Deduplicate by business_id when present; otherwise by a normalized combination of name + address + phone + website.
Output a CSV named after the query (e.g. restaurants_scraper.csv) with these columns: business_id, name, category, full_address, city, state, phone_number, website, rating, review_count, price_level, open_status, timezone, latitude, longitude, place_link, source_keyword, source_city, source_state, source_lat, source_lng. Also write failed_requests.csv with: keyword, source_city, source_state, source_lat, source_lng, error, attempts.
Print progress: coordinates selected, current batch, requests completed, raw results, deduped results, output path. Write clean modular functions: load coordinates, filter coordinates, call API, retry, parse response, deduplicate, save CSV, run CLI. After writing the code, give me the exact commands to install dependencies and run the scraper.
Variables to fill in:
- [COORDINATES_FILE]—swap this if you’re using a different coordinate source or targeting a geography outside the US (you’ll need to source your own coordinate grid and adjust the column list accordingly)
What to expect: Two new files—scraper.py and requirements.txt—plus install and run commands. Running it should walk you through picking a keyword and location scope, then produce a deduplicated CSV named after your search term and a failed_requests.csv listing anything that didn’t come back cleanly.
Follow-up prompt
Run the scraper against [TEST_KEYWORD] in [CITY_OR_STATE] and show me how many coordinates failed. If failed_requests.csv has more than a few rows, look at the error column and tell me whether it’s a rate-limit issue, a timeout issue, or something else, then suggest a fix.
Prompt 3: Add multi-keyword support
Best for: Searching several related business types in one run instead of one keyword at a time—useful when your target market spans categories that don’t share a single search term.
Use with: Claude Code desktop app
Multi-keyword support prompt
Update the scraper so it supports comma-separated keywords. Like if someone types “[KEYWORD_1], [KEYWORD_2], [KEYWORD_3]”, it should run a separate search for each keyword, then combine all the results into one CSV and remove duplicates across keywords.
After updating the code, tell me exactly how to run a multi-keyword search from the terminal.
Variables to fill in:
- [KEYWORD_1], [KEYWORD_2], [KEYWORD_3]—this is an illustrative example inside the prompt, not something you need to edit; you’ll enter your own comma-separated keywords when you actually run the scraper
What to expect: The scraper now accepts a comma-separated keyword list, runs each search, and merges everything into a single deduplicated CSV—plus instructions for running it from the terminal.
Prompt 4: Add city exclusions
Best for: Narrowing a broad state or multi-state search down to the specific metros you actually serve, without touching the rest of the scraper’s behavior.
Use with: Claude Code desktop app
City exclusions
Add support for excluding specific cities.
If the user selects a broad location scope, like an entire state or multiple states, ask whether they want to exclude any cities. The user should be able to enter comma-separated city names to exclude.
For example: [CITY_1], [CITY_2], [CITY_3]
Before scraping, remove any coordinate rows where the city matches one of the excluded cities. Make the matching case-insensitive and trim extra spaces.
After filtering, print how many coordinates were removed and how many coordinates remain.
Do not change the rest of the scraper behavior.
Variables to fill in:
- [CITY_1], [CITY_2], [CITY_3]—illustrative example inside the prompt; you’ll enter your own excluded cities when you run the scraper, not by editing this prompt
What to expect: When you pick a state or multi-state scope, the scraper now asks if you want to exclude any cities, then prints how many coordinates were removed and how many remain before it starts scraping.
Prompt 5: Add email enrichment
Best for: Turning a list of business names and websites into a list with verified contact emails, ready for a cold outbound campaign.
Use with: Claude Code desktop app
Email enrichment
Add optional email enrichment to the scraper. For each business result that has a website, visit the site and try to find a public email address. Check the homepage plus a few common contact pages (/contact, /contact-us, /about). Extract visible email addresses with a regex, but filter out junk and placeholders — asset filenames (.png, .jpg, @2x), tracking SDKs (sentry, wixpress), and template placeholders (you@, your@, name@, sample@, example.com, @domain.com, @email.com, info@company). Put the best real email in a column called “email” and any others in “all_emails”; leave blank if none found. Use short timeouts and error handling so broken or slow sites don’t stop the scraper, and run it across sites in parallel. Make it optional, since it makes the run slower.
Variables to fill in:
- None required—adjust the contact page paths (/contact, /contact-us, /about) or the junk-filter list if the sites you’re scraping use different patterns
What to expect: A new, optional enrichment pass that adds email and all_emails columns to your CSV. Expect gaps—not every business publishes a public email, and the scraper is built to skip those rather than guess.
Follow-up: import into Clay instead
If you’d rather not build the enrichment logic yourself, import the CSV into Clay and run an agent that crawls each website, finds an email, and verifies it with an email validation tool before you send anything.
Tips for better results
- Test small before you scrape big. Run the smoke test (Prompt 1) before any full-scale scrape—a large-scale run can burn through your API quota fast if something’s misconfigured.
- Use Plan Mode for large prompts. When you’re pasting a big spec like Prompt 2, use Claude Code’s Plan Mode first. It locks the AI into read-only operations so you can review the approach before anything actually gets built.
- Keep tunable values in one place. Notice Prompt 2 asks for a single CONFIG block for defaults like limit, country, and zoom—that way you can adjust search behavior later without hunting through the code.
Ready for the full story?
Read How a Google Maps scraper generated $67,500 in pipeline for a demand gen specialist featuring Bharatt Arorah of Claygen, published on the AI Lab by ActiveCampaign.
Related
More data from the AI Lab.