Google-Maps-Leadgenerierung: ein praktisches Playbook

Eine Kategorie und eine Städteliste, verwandelt in eine gefilterte, angereicherte CSV mit Leads. Vollständige Python-Schleife und die Credit-Kosten einer 100-Städte-Kampagne, August 2026.

Jede lokale Leadliste beginnt gleich: eine Kategorie, eine Menge Städte und ein Filter, der dir sagt, wen es sich lohnt anzurufen. Das ist die End-to-End-Version dieses Workflows, von der Abfrage bis zur CSV, mit den Credit-Kosten für eine echte Kampagnengröße durchgerechnet.

Wenn du die Endpoint-Referenz selbst suchst, Parameter, Antwortfelder, was eine einzelne Suche kostet, das steht in wie man Google-Maps-Ergebnisse mit Python scrapt. Dieser Beitrag ist das Playbook, das darauf aufbaut: wie man aus Maps-Ergebnissen eine Liste macht, die man einem Vertriebsmitarbeiter in die Hand geben würde.

Schritt 1: das ICP definieren, bevor du eine Abfrage schreibst

„Unternehmen in Austin” ist kein Filter. Ein brauchbares ICP für lokale Outreach braucht drei feste Größen, bevor du auch nur einen Request abschickst:

  • Kategorie. Der Suchbegriff, den du mit jeder Stadt kombinierst: „Klempner”, „Zahnarzt”, „HVAC-Betrieb”. Test ihn zuerst manuell auf Maps und prüf, dass er keine angrenzenden Kategorien zieht, die du nicht willst.
  • Eine Traktionsschwelle. Eine Mindestanzahl an Bewertungen (reviews) zeigt dir, dass das Unternehmen etabliert genug ist, um Kontaktaufnahme zu lohnen, kein Eintrag, der letzten Monat eröffnet hat.
  • Ein Schmerzsignal. Für eine Webagentur ist das ein fehlendes website-Feld. Für den Pitch eines Buchungstools könnte es ein type sein, der auf terminbasierte Arbeit hindeutet. Das Signal ist das, was dein Produkt löst.

Alles danach ist nur noch, diese Definition in großem Maßstab auszuführen.

Schritt 2: Kategorie und Stadt abfragen, paginiert

Schleif die Kategorie über deine Städteliste und behandle jede Seite als separaten, abrechenbaren Request:

import requests

API_KEY = "faf_live_..."  # dein FastAF-Key

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", [])

Zwei Seiten pro Stadt (grob 40 Orte, da eine Maps-Seite etwa 20 Ergebnisse liefert) reicht meist für mittelgroße Städte. Dichte Ballungsräume brauchen vielleicht drei oder vier, bevor der Ertrag deutlich sinkt.

Schritt 3: nach Feldern filtern, nicht nach Bauchgefühl

Hier wird das ICP aus Schritt 1 zu Code. Keine manuelle Durchsicht der Rohliste:

CATEGORY = "plumber"
CITIES = ["Austin TX", "Tampa FL", "Boise ID"]  # deine 100-Städte-Liste
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  # hat schon eine Website, nicht das ICP für einen Webagentur-Pitch
            leads.append(place)

print(f"{len(leads)} raw leads from {len(CITIES)} cities")

Dreh die Logik um für einen anderen Pitch: rating < 4.0 und reviews > 50 findet Unternehmen mit echtem Traffic und einem Reputationsproblem, ein anderes, aber ebenso gängiges ICP.

Schritt 4: nur die Shortlist anreichern, nicht den ganzen Pull

Ruf nicht jeden gescrapten Ort erneut ab, nur die, die den Filter überstanden haben. Jedes Ergebnis trägt eine place_id, die du direkt vor der Übergabe eines Leads an einen Vertriebsmitarbeiter erneut nachschlagen kannst, damit der Datensatz aktuell ist statt so alt wie der Bulk-Pull:

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]

Das ist auch die günstigere Reihenfolge: Erst zu filtern bedeutet, dass du die Anreicherungskosten nur für Leads zahlst, die du tatsächlich nutzt, nicht für jeden Ort in jeder Stadt.

Schritt 5: die CSV exportieren

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})

Das ist eine Datei, die du direkt in einen CRM-Import oder ein Cold-Outreach-Tool laden kannst.

Was kostet eine 100-Städte-Kampagne?

Ein /maps-Request kostet unabhängig von der Abfrage 5 Credits. Bei 2 Seiten pro Stadt:

Schritt Requests Credits
Discovery: 100 Städte x 2 Seiten 200 1.000
Anreicherung: ~150 Leads auf der Shortlist 150 750
Gesamt 350 1.750

Mit dem Growth-Paket (29 $ für 75.000 Credits) sind 1.750 Credits etwa 0,68 $ Anteil am Paket. Wenn du zuerst Kategorie und Filter testest: Das kostenlose Kontingent sind 500 Credits ohne Kreditkarte, genug, um Discovery und Anreicherung auf 20 bis 25 Städten laufen zu lassen, bevor du entscheidest, ob das ICP stimmt. Fehlgeschlagene Requests werden nicht abgerechnet, Credits werden reserviert, wenn ein Request startet, und zurückgegeben, wenn nichts zurückkommt, also kostet dich eine schlechte Städteabfrage nichts außer dem verschwendeten Aufruf.

Kurz zusammengefasst

Leg das ICP auf eine Kategorie, eine Traktionsschwelle und ein Schmerzsignal fest, bevor du auch nur eine Zeile Code schreibst. Frag breit ab, filtere hart, und gib Anreicherungscredits nur für Leads aus, die den Filter schon bestanden haben. Ein vollständiger 100-Städte-Sweep mit Anreicherung landet unter 2.000 Credits, klein genug, dass der begrenzende Faktor bei so einer Kampagne nie die API-Rechnung ist, sondern wie gut der Filter ist.