# Home Services Google Maps Lead Generator (`clura/home-services-google-maps-lead-generator`) Actor

Scrapes HVAC, plumbing, electrical, roofing, solar, garage door, pest control, and landscaping contractor leads from Google Maps by location, with email/services/social enrichment from each contractor's website. Drives the real Clura Chrome extension headlessly.

- **URL**: https://apify.com/clura/home-services-google-maps-lead-generator.md
- **Developed by:** [Clura](https://apify.com/clura) (community)
- **Categories:** Lead generation, AI, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 leads without enrichments

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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

## Home Services Google Maps Lead Generator

Scrapes HVAC, plumbing, electrical, roofing, solar, garage door, pest control, and landscaping contractor leads directly from Google Maps by location — business name, rating, category, address, phone, website, and a direct Google Maps listing link — then visits each contractor's own website to detect email addresses, the specific services they offer, whether they provide 24/7 emergency service, and their social media profiles.

Built on a real Chrome browser driven by the actual Clura Chrome extension (not a lightweight HTTP scraper), so it holds up against the same anti-bot measures a real user's browser would face, and self-heals its selectors with AI if Google changes Maps' markup.

### How it works

1. **Search Google Maps** — for each location you provide, the actor searches Google Maps for each of your chosen contractor types, rotating across all of them to surface more distinct businesses per area than a single generic query would. Covers 8 trades by default: HVAC (9 search-term variants), Plumbing, Electrical, Roofing, Solar, Garage Door, Pest Control, and Landscaping — or supply your own custom search terms for any other trade.
2. **Extract listing data** — business name, rating, category, address, phone, website, and Google Maps URL are read directly from the search results.
3. **Deduplicate** — contractors found under more than one search term are merged into one record, keyed on phone number first, then website domain.
4. **Enrich from each contractor's website** — the actor visits each website's homepage once and extracts:
   - The first email address found on the page
   - Which of 36 services across all 8 trades the page mentions — AC Installation/Repair, Heating Repair, Furnace Install/Repair, Boiler Repair, Heat Pump Service, Duct Cleaning, Indoor Air Quality, Refrigeration, Plumbing Repair, Drain Cleaning, Water Heater Installation, Leak Detection, Electrical Panel Upgrade, Rewiring, Lighting Installation, Roof Replacement/Repair, Gutter Installation, Solar Panel Install/Repair, Garage Door Repair/Installation, Pest Control, Termite Treatment, Rodent Control, Lawn Care, Landscaping Design, Tree/Shrub Care, and more
   - Whether they explicitly advertise 24/7 emergency service
   - Facebook, Instagram, LinkedIn, and Twitter/X profile links

### Input

| Field | Type | Description |
|---|---|---|
| `locations` | array (required) | Zip codes or city/state to search, e.g. `["75201", "Austin, TX"]`. Every search term runs once per location. |
| `searchTerms` | array | Contractor types to search for. Defaults to a rotation across all 8 trades listed above if left empty — add your own for a custom trade or search. |
| `maxLeadsPerSearch` | integer | Max leads per location × search-term combination. Default 30. |
| `maxPagesPerSearch` | integer | Max scroll/pagination steps per search before stopping. Default 5. |
| `enrichWebsite` | boolean | Visit each lead's website to extract email/services/24-7-flag/social links. Default true. |
| `openaiApiKey` | string | Only used if Google Maps' markup has changed enough that the built-in selectors stop working, to re-detect them via AI. Optional. |
| `proxyConfiguration` | object | Apify Proxy settings. |

### Output

Each record: `name`, `rating`, `category`, `address`, `phone`, `website`, `mapsUrl`, `searchTerm`, `location`, `email`, `services` (array), `emergency24_7` (boolean), `socialLinks` (object).

### What this actor does NOT do (please read before running)

- **No email verification.** Extracted emails are exactly what's published on the contractor's website — there's no DNS/SMTP deliverability check.
- **Homepage only.** Website enrichment reads the contractor's homepage — it doesn't crawl into separate Contact/About/Services pages.
- **No review count.** Google Maps' search-results list doesn't render review count for every listing, so it isn't a reliable field to offer here.
- Results per search are capped by what Google Maps itself returns for a single query (typically well under 200).

### Who this is for

- **Home services SaaS vendors** (dispatch, invoicing, field service management) sourcing contractors to sell into.
- **Equipment and parts suppliers** finding local contractors to sell to.
- **Marketing agencies** running lead-gen for home-services clients.
- **Insurance and home-warranty programs** identifying certified contractors for repair networks.
- **PE and franchise roll-up acquirers** — home services is one of the most actively consolidated sectors in the market right now (documented platforms exist for HVAC, plumbing, roofing, pest control, and more).
- **Recruiting** — sourcing technicians and companies hiring in a specific market.
- **Market research** — contractor density, service mix, and emergency-service coverage by city.

# Actor input Schema

## `locations` (type: `array`):

Zip codes or city/state to search, e.g. \["75201", "Austin, TX"]. Every search term below is run once per location.

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

Home services business types to search for, rotated across each location to surface more leads (Google Maps' ranking varies by query wording). Defaults to a rotation across all 8 trades if left empty: HVAC Company, AC Repair Service, Heating Contractor, Air Conditioning Contractor, Furnace Repair Service, Duct Cleaning Service, Commercial HVAC Contractor, Refrigeration Service, Indoor Air Quality Company, Plumber, Plumbing Company, Electrician, Electrical Contractor, Roofing Contractor, Roof Repair Service, Solar Panel Installer, Garage Door Repair Service, Pest Control Service, Termite Control Company, Landscaping Company, Lawn Care Service. Add your own for a custom trade or search.

## `maxLeadsPerSearch` (type: `integer`):

Maximum leads to collect per location x search term combination.

## `maxPagesPerSearch` (type: `integer`):

Maximum pagination steps (scrolls) per search before stopping.

## `enrichWebsite` (type: `boolean`):

Visit each lead's website homepage to extract email, detected services across all 8 trades, 24/7 emergency availability, and social media links.

## `crawlContactPages` (type: `boolean`):

If the homepage has no email, follow one Contact/About-style link on the site to look there too. Costs one extra page visit per lead that needs it. Default false.

## `openaiApiKey` (type: `string`):

Used only if Google Maps' markup has changed enough that the built-in recipe stops working, to re-map fields via AI. Falls back to the OPENAI\_API\_KEY env var if omitted.

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

Apify Proxy settings to route the browser's traffic through.

## `recipeOverride` (type: `object`):

Advanced use only. Overrides the actor's built-in Google Maps selectors.

## Actor input object example

```json
{
  "locations": [
    "Austin, TX"
  ],
  "searchTerms": [
    "Plumber"
  ],
  "maxLeadsPerSearch": 5,
  "maxPagesPerSearch": 2,
  "enrichWebsite": true,
  "crawlContactPages": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `leads` (type: `string`):

Every lead found, one row per business — the actor's main result.

## `runSummary` (type: `string`):

Status, total leads found, searches run, searches that needed the contact-page fallback, and how many leads had an email — one JSON record for the whole 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("clura/home-services-google-maps-lead-generator").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("clura/home-services-google-maps-lead-generator").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 clura/home-services-google-maps-lead-generator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,clura/home-services-google-maps-lead-generator"
        }
    }
}

```

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/fdoLoo1ASuPYnGGsQ/builds/BSmq3U7zhOfhAd9XE/openapi.json
