Lead generation su Google Maps: un playbook pratico
Una categoria e una lista di città diventano un CSV di lead filtrato e arricchito. Loop Python completo e costo in crediti su 100 città, agosto 2026.

Ogni lista di lead locale parte allo stesso modo: una categoria, un insieme di città, e un filtro che ti dice chi vale davvero la pena chiamare. Questa è la versione end-to-end di quel workflow, dalla query al CSV, con il costo in crediti calcolato per una campagna di dimensione reale.
Se ti serve il riferimento dell’endpoint in sé, parametri, campi della risposta, quanto costa una singola ricerca, è coperto in come estrarre i risultati di Google Maps con Python. Questo post è il playbook costruito sopra: come trasformare i risultati Maps in una lista da consegnare a un venditore.
Passo 1: definisci l’ICP prima di scrivere una query
“Attività ad Austin” non è un filtro. Un ICP utilizzabile per l’outreach locale ha bisogno di tre cose fissate prima di eseguire una sola richiesta:
- Categoria. Il termine di ricerca che abbinerai a ogni città: “idraulico”, “dentista”, “tecnico climatizzazione”. Testalo prima manualmente su Maps e controlla che non peschi categorie adiacenti che non vuoi.
- Una soglia di trazione. Un numero minimo di recensioni (
reviews) ti dice che l’attività è abbastanza consolidata da valere il contatto, non un’inserzione aperta il mese scorso. - Un segnale di dolore. Per una web agency, è un campo
websitemancante. Per la vendita di uno strumento di prenotazione, potrebbe essere untypeche implica lavoro su appuntamento. Il segnale è qualunque cosa risolva il tuo prodotto.
Tutto il resto è solo eseguire quella definizione su scala.
Passo 2: interroga categoria e città, con paginazione
Fai il loop della categoria sulla tua lista di città, e tratta ogni pagina come una richiesta fatturabile separata:
import requests
API_KEY = "faf_live_..." # la tua chiave FastAF
def maps_search(query, page=0):
resp = requests.get(
"https://api.fastaf.co/v1/maps",
params={"query": query, "page": page},
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=60,
)
resp.raise_for_status()
return resp.json().get("search_results", [])
Due pagine per città (circa 40 attività, dato che una pagina Maps porta circa 20 risultati) di solito bastano per città di medie dimensioni. Le metropoli dense possono richiederne tre o quattro prima di arrivare ai rendimenti decrescenti.
Passo 3: filtra sui campi, non sul giudizio
È qui che l’ICP del passo 1 diventa codice. Nessuna revisione manuale della lista grezza:
CATEGORY = "plumber"
CITIES = ["Austin TX", "Tampa FL", "Boise ID"] # la tua lista di 100 città
MIN_REVIEWS = 25
MIN_RATING = 4.0
PAGES_PER_CITY = 2
leads = []
for city in CITIES:
for page in range(PAGES_PER_CITY):
for place in maps_search(f"{CATEGORY} in {city}", page=page):
if place.get("reviews", 0) < MIN_REVIEWS:
continue
if place.get("rating", 0) < MIN_RATING:
continue
if place.get("website"):
continue # ha già un sito, non è l'ICP per una pitch da web agency
leads.append(place)
print(f"{len(leads)} lead grezzi da {len(CITIES)} città")
Inverti la logica per una pitch diversa: rating < 4.0 e reviews > 50 trova attività con traffico reale e un problema di reputazione, un ICP diverso ma altrettanto comune.
Passo 4: arricchisci la shortlist, non l’intera estrazione
Non rifare il fetch di ogni attività estratta, solo di quelle sopravvissute al filtro. Ogni risultato porta un place_id, che puoi ricercare di nuovo appena prima che un lead vada a un venditore, così il dato è aggiornato invece che vecchio di quanti giorni fa era l’estrazione massiva:
def maps_lookup(place_id):
resp = requests.get(
"https://api.fastaf.co/v1/maps",
params={"place_id": place_id},
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=60,
)
resp.raise_for_status()
results = resp.json().get("search_results", [])
return results[0] if results else {}
enriched = [maps_lookup(lead["place_id"]) if lead.get("place_id") else lead for lead in leads]
Questo è anche l’ordine di operazioni più economico: filtrare prima significa pagare il costo di arricchimento solo sui lead che userai davvero, non su ogni attività di ogni città.
Passo 5: esporta il CSV
import csv
with open("leads.csv", "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["title", "phone", "address", "rating", "reviews", "type"])
writer.writeheader()
for lead in enriched:
writer.writerow({k: lead.get(k, "") for k in writer.fieldnames})
Questo è un file che puoi importare direttamente in un CRM o in uno strumento di outreach a freddo.
Quanto costa una campagna su 100 città?
Una richiesta /maps costa 5 crediti indipendentemente dalla query. A 2 pagine per città:
| Passo | Richieste | Crediti |
|---|---|---|
| Discovery: 100 città x 2 pagine | 200 | 1.000 |
| Arricchimento: ~150 lead selezionati | 150 | 750 |
| Totale | 350 | 1.750 |
Sul pacchetto Growth ($29 per 75.000 crediti), 1.750 crediti sono circa $0,68 del pacchetto. Se stai prima testando categoria e filtro, il piano gratuito è di 500 crediti senza carta, abbastanza per fare discovery e arricchimento su 20-25 città prima di decidere se l’ICP è giusto. Le richieste fallite non vengono fatturate, i crediti vengono riservati quando una richiesta parte e restituiti se non torna nulla, quindi una query su una città sbagliata non ti costa nulla oltre alla chiamata sprecata.
In breve
Fissa l’ICP su una categoria, una soglia di trazione e un segnale di dolore prima di scrivere codice. Interroga in ampiezza, filtra a fondo, e spendi crediti di arricchimento solo sui lead già passati dal filtro. Una scansione completa su 100 città con arricchimento sta sotto i 2.000 crediti, abbastanza poco che il vincolo su una campagna del genere non è mai la bolletta dell’API, è quanto è buono il filtro.