Google People Also Ask und Autocomplete für die Keyword-Recherche scrapen – Python-Leitfaden

Praktischer Leitfaden zum Scrapen von Google Autocomplete, People Also Ask und Related Searches mit Python, httpx und Playwright – inklusive ProxyHat-Setup, Dedup-Logik und CSV-Export für die Keyword-Recherche.

Scrape Google People Also Ask and Autocomplete for Keyword Research (Python Guide)
In diesem Artikel

Wer People Also Ask und Autocomplete für die Keyword-Recherche scrapen will, greift auf drei kostenlose, aber extrem ergiebige Google-Datenquellen zu: die Autocomplete-Suggest-API, die PAA-Box (People Also Ask) und die Related-Searches-Leiste. Dieser Leitfaden zeigt, wie du mit Python, httpx und Playwright daraus hunderte Longtail-Keywords pro Seed generierst – und warum residential Proxies mit Geo-Targeting unverzichtbar sind, sobald du skaliert.

Warum People Also Ask und Autocomplete für die Keyword-Recherche scrapen?

Google veröffentlicht keine vollständigen Suchvolumina, aber die Autocomplete-Vorschläge, die PAA-Fragen und die Related Searches sind öffentlich sichtbar und spiegeln echtes Suchverhalten wider. Anders als bei kommerziellen Keyword-Tools zahlst du nichts pro Query und bekommst dafür die exakt gleichen Vorschläge, die ein echter Nutzer in der Google-Suche sieht. Für SEO-Teams, die FAQ-Schemata bauen, Content-Lücken finden oder Longtail-Cluster identifizieren wollen, sind diese drei Quellen die effizientesten freien Datenpunkte überhaupt.

Die drei Quellen lassen sich sauber nach Suchintenz unterscheiden:

QuelleEndpoint / DOMIntenz-SignalTypische Ausbeute pro Seed
Autocompletesuggestqueries.google.com/complete/search?client=chrome&q=Was Nutzer eintippen (informational + transactional)10 Vorschläge pro Buchstabenkombination
People Also AskSERP-Box mit Akkordeon-ElementenExplizite Fragen (FAQ-freundlich)4–8 initiale Fragen, rekursiv erweiterbar
Related SearchesUnterer SERP-BereichThematisch benachbarte Queries8 Vorschläge

Technischer Kontext: Warum Google diese Daten frei gibt – und trotzdem drosselt

Die Autocomplete-API ist technisch kein offizielles öffentliches API, sondern der Endpoint, den der Chrome-Browser selbst ansteuert, um Suchvorschläge zu laden. Die Struktur ist dokumentiertes Verhalten, kein Vertrag – Google kann das Format jederzeit ändern. Der Endpoint google.com liefert bei client=chrome ein kompaktes JSON mit UTF-8-kodierten Vorschlägen, während client=firefox ein etwas anderes Array-Layout zurückgibt.

PAA-Fragen sind Teil der regulären SERP und werden serverseitig gerendert. Jedes Akkordeon-Element lädt beim Aufklappen per XHR weitere Fragen nach – das ist der Grund, warum einfache requests-Aufrufe hier scheitern und ein Headless-Browser wie Playwright nötig wird. Die offizielle Playwright-Dokumentation beschreibt die page.click- und page.wait_for_selector-Muster, die du für das rekursive Aufklappen brauchst.

Das eigentliche Problem bei Skalierung: Google drosselt pro IP aggressiv. In der Praxis siehst du nach etwa 50–100 Requests pro IP innerhalb von 10 Minuten CAPTCHAs oder leere Responses. Hinzu kommt Locale-Bias: Autocomplete-Vorschläge unterscheiden sich stark je nach Land und Stadt. Ein Query „pizza“ liefert in Berlin andere Vorschläge als in Chicago. Wer sauber lokalisierte Keyword-Sets bauen will, braucht residential Proxies mit Country- und City-Targeting.

Proxy-Setup mit ProxyHat: Geo-Targeting für saubere Suggestions

ProxyHat bietet residential Proxies, die du über den Username steuerst. Für Deutschland-Berlin-Sessions sieht die Konfiguration so aus:

# HTTP-Proxy mit Geo-Targeting (Berlin, Deutschland)
HTTP_PROXY = "http://user-country-DE-city-berlin:pass@gate.proxyhat.com:8080"

# SOCKS5-Variante für Playwright / Browser-Kontexte
SOCKS5_PROXY = "socks5://user-country-DE-city-berlin:pass@gate.proxyhat.com:1080"

# Sticky Session für konsistente SERP-Ergebnisse
STICKY_PROXY = "http://user-country-DE-session-abc123:pass@gate.proxyhat.com:8080"

Sticky Sessions sind wichtig, wenn du mehrere SERP-Seiten derselben Query hintereinander lädst und dabei nicht die IP wechseln willst – sonst liefert Google dir inkonsistente Layouts. Für Autocomplete-Massencabrufe nutzt du besser rotierende IPs, also ohne -session--Flag. Details zu den Standorten findest du unter /de/locations, Pricing unter /de/pricing.

Code-Block 1: Autocomplete mit curl und ProxyHat testen

Bevor du Python baust, prüfe den Endpoint manuell. Der Chrome-Client liefert JSON, der Firefox-Client ein flacheres Array:

# Autocomplete über ProxyHat mit Berlin-IP abrufen
curl -x "http://user-country-DE-city-berlin:pass@gate.proxyhat.com:8080" \
  "https://suggestqueries.google.com/complete/search?client=chrome&q=best%20running%20shoes" \
  -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" \
  -H "Accept-Language: de-DE,de;q=0.9"

Die Antwort ist ein Array: [query, [suggestions], [types], [metadata]]. Die Vorschläge sind bereits UTF-8-dekodiert, du musst nur das Array flachklopfen.

Code-Block 2: Seed-zu-Longtail-Expander mit httpx

Ein einzelnes Seed-Keyword liefert 10 Vorschläge. Wenn du das Seed mit den Buchstaben a–z und Modifikatoren wie „how", „what", „best", „vs" kombinierst, bekommst du aus einem Seed schnell 260+ Longtail-Keywords. Hier die httpx-Implementierung mit Retry-Logik und Proxy-Rotation:

import httpx
import asyncio
import itertools
from typing import List

PROXY = "http://user-country-DE-city-berlin:pass@gate.proxyhat.com:8080"
AUTOCOMPLETE_URL = "https://suggestqueries.google.com/complete/search"

HEADERS = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36",
    "Accept-Language": "de-DE,de;q=0.9,en;q=0.8",
}

MODIFIERS = ["", "how ", "what ", "best ", "vs ", "why ", "is ", "buy "]
LETTERS = [chr(c) for c in range(ord("a"), ord("z") + 1)]

async def fetch_suggestions(client: httpx.AsyncClient, query: str) -> List[str]:
    params = {"client": "chrome", "q": query}
    for attempt in range(3):
        try:
            r = await client.get(AUTOCOMPLETE_URL, params=params, headers=HEADERS, timeout=10.0)
            if r.status_code == 200 and r.json():
                return r.json()[1] or []
        except (httpx.HTTPError, httpx.JSONDecodeError) as e:
            print(f"retry {attempt} for '{query}': {e}")
            await asyncio.sleep(1.5 * (attempt + 1))
    return []

async def expand_seed(seed: str) -> List[str]:
    prefixes = [f"{seed} {l}" for l in LETTERTERS] + [f"{m}{seed}" for m in MODIFIERS]
    async with httpx.AsyncClient(proxy=PROXY) as client:
        tasks = [fetch_suggestions(client, p) for p in prefixes]
        results = await asyncio.gather(*tasks, return_exceptions=True)
    suggestions = set()
    for r in results:
        if isinstance(r, list):
            suggestions.update(r)
    return sorted(suggestions)

if __name__ == "__main__":
    keywords = asyncio.run(expand_seed("running shoes"))
    print(f"{len(keywords)} Keywords gefunden")

Achtung: 33 parallele Requests sind schon im Drosselbereich. Setze einen Semaphore(10) um die Concurrency zu begrenzen, sonst bekommst du 429s.

Code-Block 3: PAA-Fragen mit Playwright rekursiv aufklappen

PAA ist der schwierigste Teil, weil die Fragen in einem Akkordeon liegen und erst beim Klicken weitere Fragen nachladen. Playwright mit SOCKS5-Proxy ist hier der Standardweg:

from playwright.async_api import async_playwright
import asyncio
import json

SOCKS5 = "socks5://user-country-DE-city-berlin:pass@gate.proxyhat.com:1080"
QUERY = "best running shoes for flat feet"

def extract_paa(page):
    return page.evaluate("""() => {
      const items = [...document.querySelectorAll('div[role="listitem"]')];
      return items.map(el => {
        const q = el.querySelector('span[jsname]')?.innerText || '';
        const cite = el.querySelector('a[href]')?.href || '';
        return {question: q, source: cite};
      }).filter(x => x.question);
    }""")

async def scrape_paa(query: str, max_depth: int = 4):
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=True,
            proxy={"server": SOCKS5}
        )
        ctx = await browser.new_context(locale="de-DE")
        page = await ctx.new_page()
        await page.goto(f"https://www.google.com/search?q={query}&hl=de&gl=de", wait_until="domcontentloaded")
        await page.wait_for_selector('div[role="listitem"]', timeout=15000)

        seen = set()
        for depth in range(max_depth):
            accordions = await page.query_selector_all('div[role="listitem"] div[jsname]')
            for acc in accordions[:8]:
                try:
                    await acc.click(timeout=3000)
                    await page.wait_for_timeout(800)
                except Exception:
                    continue
            rows = await extract_paa(page)
            for r in rows:
                if r["question"] not in seen:
                    seen.add(r["question"])
        await browser.close()
        return list(seen)

if __name__ == "__main__":
    questions = asyncio.run(scrape_paa(QUERY))
    print(json.dumps(questions, ensure_ascii=False, indent=2))

Die wait_for_timeout(800) ist wichtig – Google lädt die Folgefragen asynchron nach. Zu schnelles Klicken überspringt Fragen. Die source-URL ist gleichzeitig ein Backlink-Kandidat für dein FAQ-Content-Marketing.

Related Searches sind das einfachste Ziel – sie stehen als statische Links unten auf der SERP:

async def scrape_related(page, query):
    await page.goto(f"https://www.google.com/search?q={query}&hl=de&gl=de", wait_until="domcontentloaded")
    await page.wait_for_selector('a[href*="/search?q="], div[id*="related"]', timeout=10000)
    return await page.evaluate("""() => {
      const links = [...document.querySelectorAll('a[href*="/search?q="]')];
      const related = new Set();
      for (const a of links) {
        const u = new URL(a.href);
        const q = u.searchParams.get('q');
        if (q && !q.startsWith('http')) related.add(q);
      }
      return [...related];
    }""")

Code-Block 5: Dedup, Intent-Clustering und CSV-Export

Roh-Listen sind wertlos. Du musst normalisieren, dedupen und nach Suchintenz clustern. Hier eine kompakte Pipeline:

import csv
import re
from collections import defaultdict

INTENT_RULES = {
    "transactional": [r"\b(kaufen|bestellen|price|buy|deal|gutschein)\b"],
    "navigational":  [r"\b(login|official|website|site:)\b"],
    "informational": [r"\b(wie|was|warum|how|what|why|guide|tutorial)\b"],
}

def normalize(q: str) -> str:
    return re.sub(r"\s+", " ", q.strip().lower())

def classify(q: str) -> str:
    for intent, patterns in INTENT_RULES.items():
        if any(re.search(p, q) for p in patterns):
            return intent
    return "commercial"

def build_dataset(autocomplete, paa, related):
    raw = autocomplete + [p["question"] if isinstance(p, dict) else p for p in paa] + related
    seen = {}
    for q in raw:
        n = normalize(q)
        if n and n not in seen:
            seen[n] = {"keyword": n, "intent": classify(n), "source": "mixed"}
    return list(seen.values())

def export_csv(rows, path="keywords.csv"):
    with open(path, "w", newline="", encoding="utf-8") as f:
        w = csv.DictWriter(f, fieldnames=["keyword", "intent", "source"])
        w.writeheader()
        w.writerows(rows)

if __name__ == "__main__":
    rows = build_dataset(
        autocomplete=["best running shoes", "running shoes sale"],
        paa=[{"question": "How to choose running shoes?", "source": ""}],
        related=["running shoes vs trainers"],
    )
    export_csv(rows)
    print(f"{len(rows)} Keywords exportiert")

Für ernsthaftes Intent-Clustering lohnt sich danach ein Embedding-Modell (z. B. sentence-transformers), das die Keywords semantisch gruppiert. Das übersteigt aber den Rahmen dieses Leitfadens – die Regel-basierte Klassifikation reicht für einen ersten FAQ-Plan.

Häufige Fehler und Edge Cases

  • Zu hohe Concurrency ohne Proxy-Rotation – nach ~80 Requests / 10 Min / IP liefert Google leere Arrays oder 429. Drossel auf 5–10 gleichzeitige Requests.
  • Falscher User-Agent – der Chrome-Endpoint erwartet einen Chrome-UA. Mit einem Python-requests-Default-UA bekommst du manchmal HTML statt JSON.
  • Locale-Header ignoriertAccept-Language und gl-Parameter müssen zur Proxy-Geo passen, sonst mischt Google Regionen.
  • PAA-Selektor bricht – Google ändert die DOM-Struktur regelmäßig. Nutze robuste Selektoren wie div[role="listitem"] statt kryptischer jsname-Attribute.
  • Kein Retry bei Transient-Errors – ein Circuit Breaker (z. B. 3 Fails → 60 s Pause) verhindert, dass du ganze Proxy-Pools verbrennst.

Ethik und Skalierung: öffentliche Daten, aber höflich

Autocomplete-Vorschläge und PAA-Fragen sind öffentlich sichtbare Daten – es gibt keine Paywall und keine Authentifizierung. Trotzdem solltest du throttle politely: 1–2 Requests pro Sekunde pro IP, Pausen zwischen Bursts, und Respekt vor robots.txt. Für produktive Workloads im großen Stil bevorzugt Google offizielle APIs – die Custom Search JSON API deckt allerdings keine Autocomplete-Daten ab, weshalb Scraping für diese spezifische Datenquelle die einzige praktische Option bleibt.

Rechtlich relevant: In der EU greift die DSGVO nicht für anonyme Suchvorschläge, aber personenbezogene Queries (z. B. Namenssuchen) solltest du herausfiltern. Für kommerzielle Keyword-Datenbanken empfiehlt sich eine anonymisierte Speicherung ohne Timestamps, die einzelne Nutzer identifizierbar machen könnten.

Key Takeaways

  • Autocomplete, PAA und Related Searches decken drei verschiedene Intenz-Signale ab – kombiniere sie, nicht nur eine Quelle.
  • Ein Seed-Keyword mit a–z- und Modifikator-Prefixen liefert 200+ Longtail-Vorschläge – das ist der billigste Keyword-Funnel, den es gibt.
  • PAA ist rekursiv: Jeder Klick lädt neue Fragen, also klappre 3–4 Level tief auf.
  • Residential Proxies mit City-Targeting (z. B. user-country-DE-city-berlin) sind nötig für saubere lokalisierte Suggestions und um IP-Drosseln zu umgehen.
  • Normalisiere, dedupe und klassifiziere nach Intenz, bevor du exportierst – Rohlisten sind nicht produktionsreif.
  • Höflich drosseln: 1–2 req/s/IP, offizielle APIs bevorzugen, wo sie existieren.

Wenn du das Setup produktiv drehen willst, schau dir unsere Web-Scraping-Use-Cases und die SERP-Tracking-Seite an. Die vollständige ProxyHat-Dokumentation findest du unter docs.proxyhat.com.

Häufig gestellte Fragen

Was bedeutet People Also Ask und Autocomplete für die Keyword-Recherche scrapen?

Es bezeichnet das automatisierte Abrufen von Google-Suchvorschlägen (Autocomplete), der People-Also-Ask-Box und der Related Searches, um daraus Longtail-Keywords, FAQ-Fragen und Intent-Cluster für die SEO-Content-Planung zu generieren. Typische Tools sind Python mit httpx für die Suggest-API und Playwright für das rekursive Aufklappen der PAA-Akkordeons.

Warum sind Proxies wichtig beim Scrapen von Autocomplete und PAA?

Google drosselt Autocomplete- und SERP-Aufrufe pro IP nach etwa 50–100 Requests innerhalb von 10 Minuten mit CAPTCHAs oder leeren Responses. Zudem liefern Autocomplete und PAA unterschiedliche Vorschläge je nach Land und Stadt. Residential Proxies mit Country- und City-Targeting umgehen die Drossel und liefern konsistente lokalisierte Suggestions.

Welche Proxy-Art eignet sich am besten für Keyword-Scraping?

Residential Proxies sind die beste Wahl, weil sie echte ISP-IPs verwenden und von Google nicht als Rechenzentrum erkannt werden. Datacenter-Proxies werden schneller geblockt. Für Browser-basierte PAA-Scraping mit Playwright eignet sich SOCKS5 (Port 1080), für reine API-Aufrufe des Autocomplete-Endpoints HTTP (Port 8080).

Wie vermeide ich Blocks beim Scrapen von People Also Ask?

Drossel auf 1–2 Requests pro Sekunde und IP, rotiere residential Proxies, nutze realistische User-Agent- und Accept-Language-Header passend zur Proxy-Geo, und baue Retry-Logik mit exponentiellem Backoff ein. Für PAA mit Playwright zusätzlich Wartezeiten zwischen Akkordeon-Klicks einbauen, damit asynchrone Fragen-Loads nicht übersprungen werden.

Ist das Scrapen von Google Autocomplete legal?

Autocomplete-Vorschläge und PAA-Fragen sind öffentlich sichtbare Daten ohne Authentifizierung. Das automatisierte Abrufen verstößt jedoch potenziell gegen die Google-Nutzungsbedingungen. Für interne Keyword-Recherche in moderatem Umfang wird es praktiziert, bei kommerzieller Wiederverwendung solltest du rechtlichen Rat einholen und offizielle APIs prüfen, wo sie existieren.

Bereit loszulegen?

Residential-, ISP- und Mobile-Proxys in über 148 Ländern. Erstelle ein kostenloses Konto.

Kostenloses Konto erstellen
← Zurück zum Blog