Keyword-Recherche ist oft der Flaschenhals jeder Content- und SEO-Strategie. Wer Google People Also Ask und Autocomplete für Keyword-Recherche scrapen will (dieser Python-Leitfaden zeigt wie), erschließt sich drei kostenlose Datenquellen, die kommerzielle Keyword-Tools für teures Geld verkaufen: Autocomplete-Vorschläge, People Also Ask (PAA)-Fragen und Related Searches. Keine API-Keys, keine monatlichen Abos – nur öffentliche Suggest-Daten, die mit den richtigen Proxies und etwas Python-Code in strukturierte Keyword-Listen verwandelt werden können.
Dieser Leitfaden richtet sich an SEO-Spezialisten und Entwickler, die eigene Keyword-Research-Tooling bauen. Wir behandeln die drei Datenquellen, einen Seed-zu-Longtail-Expander, Proxy-Setup mit ProxyHat, Playwright-basierte PAA-Extraktion, Deduplizierung und Intent-Clustering – alles mit lauffähigem Python-Code.
Die drei kostenlosen Keyword-Goldgruben – und wie sie Suchintention abbilden
Google liefert auf unterschiedlichen Wegen Keyword-Vorschläge, die jeweils unterschiedliche Suchintention-Schichten abdecken. Wer alle drei kombiniert, bekommt ein deutlich vollständigeres Bild als mit einem einzigen kommerziellen Tool.
| Quelle | Datenformat | Intent-Fokus | Typische Ausbeute pro Seed |
|---|---|---|---|
| Autocomplete (Suggest API) | JSON-Array, 10 Vorschläge | Informational & transaktional (Long-Tail) | 10–130 Vorschläge |
| People Also Ask (PAA) | Frage-Akkordeons in SERP | Informational (Frage-basiert) | 4–20+ Fragen, rekursiv erweiterbar |
| Related Searches | Text-Links am SERP-Ende | Mixed (semantische Verwandte) | 8–12 Keywords |
Autocomplete – die Suggest-API
Googles Autocomplete-Dienst ist unter suggestqueries.google.com/complete/search?client=chrome&q=… erreichbar und liefert ein JSON-Array mit bis zu 10 Vorschlägen pro Anfrage. Der Endpunkt ist nicht offiziell dokumentiert, wird aber vom Chrome-Browser selbst genutzt und ist seit Jahren stabil. Laut Wikipedia nutzt Google über 200 Signale – darunter Standort, Suchverlauf und Trend – um Vorschläge zu personalisieren. Für Keyword-Recherche ist das wichtig: Ohne Geo-Kontext liefert Google US-Last-Vorschlägen, die für einen deutschen Markt irrelevant sein können.
People Also Ask – Frage-basierte Intent-Schicht
PAA-Boxen erscheinen in den meisten SERPs und zeigen 4 initiale Fragen an. Klickt man eine auf, erscheinen 2–3 neue Fragen darunter – rekursiv. Aus 4 Fragen können so schnell 20+ werden. Jede PAA-Frage enthält zusätzlich eine Antwortquelle (URL), was direkt für Content-Planung und FAQ-Schema-Markup nutzbar ist.
Related Searches – semantische Nachbarn
Am Ende jeder SERP listet Google 8–12 „Verwandte Suchanfragen“. Diese sind besonders wertvoll für thematische Clusterung und Content-Hub-Planung, da sie semantische Nachbarn liefern, die in Autocomplete oft fehlen.
Seed-zu-Longtail-Expander: Aus einem Keyword werden Hunderte
Ein einzelnes Seed-Keyword liefert über Autocomplete nur 10 Vorschlägen. Der Trick ist, das Seed mit Präfixen und Suffixen zu kombinieren: das Alphabet (a–z) und gängige Modifier wie „how“, „what“, „best“, „vs“, „kosten“, „tipps“. Aus einem Seed wie „python webscraping“ entstehen so 26 × 2 + 11 × 2 = 74 Kombinationen, die jeweils 10 Vorschlägen zurückgeben – bis zu 740 Roh-Keywords, nach Deduplizierung oft 200–300 einzigartige Long-Tail-Varianten.
import httpx
import json
from typing import List
PROXY_URL = "http://user-country-DE-city-berlin:pass@gate.proxyhat.com:8080"
def fetch_autocomplete(query: str, client: httpx.Client) -> List[str]:
"""Fetch Google Autocomplete suggestions for a single query."""
url = "https://suggestqueries.google.com/complete/search"
params = {"client": "chrome", "q": query, "hl": "de", "gl": "de"}
try:
resp = client.get(url, params=params, timeout=10.0)
resp.raise_for_status()
data = resp.json()
if isinstance(data, list) and len(data) > 1:
return [s for s in data[1]]
return []
except (httpx.HTTPError, json.JSONDecodeError) as exc:
print(f"[!] Autocomplete error for '{query}': {exc}")
return []
def expand_seed(keyword: str, client: httpx.Client) -> set:
"""Expand a seed keyword using a-z prefixes and common modifiers."""
alphabet = "abcdefghijklmnopqrstuvwxyz"
modifiers = ["how", "what", "why", "best", "vs", "near me",
"2025", "kosten", "tipps", "tutorial", "beispiel"]
queries = {keyword}
for letter in alphabet:
queries.add(f"{letter} {keyword}")
queries.add(f"{keyword} {letter}")
for mod in modifiers:
queries.add(f"{mod} {keyword}")
queries.add(f"{keyword} {mod}")
all_suggestions = set()
for q in sorted(queries):
suggestions = fetch_autocomplete(q, client)
all_suggestions.update(suggestions)
print(f"[{q}] -> {len(suggestions)} suggestions")
return all_suggestions
with httpx.Client(proxy=PROXY_URL) as client:
expanded = expand_seed("python webscraping", client)
print(f"\nTotal unique suggestions: {len(expanded)}")Warum schnelle Autocomplete- und PAA-Aufrufe Rate Limits auslösen
Google drosselt Anfragen pro IP-Adresse aggressiv. Wer 100+ Autocomplete-Calls in wenigen Sekunden von einer IP abfeuert, bekommt HTTP 429 (Too Many Requests) oder leere Antworten zurück. Datacenter-IPs sind besonders anfällig, da Google sie als Bot-Traffic erkennt. Laut MDN signalisiert der 429-Status, dass der Client zu viele Anfragen in einem bestimmten Zeitraum gesendet hat.
Hinzu kommt das Lokalisierungsproblem: Autocomplete-Ergebnisse sind stark vom Standort abhängig. Eine Anfrage von einer US-Datacenter-IP liefert US-Trends, nicht deutsche. Residential Proxies mit Geo-Targeting lösen beide Probleme gleichzeitig:
- IP-Rotation: Jede Anfrage kann über eine andere Wohn-IP laufen, wodurch Per-IP-Rate-Limits umgangen werden.
- Geo-Kontext: Mit
user-country-DE-city-berlinim ProxyHat-Benutzernamen erzwingen Sie deutsche Vorschläge aus Berlin – sauber lokalisiert. - Geringere Erkennungsrate: Residential IPs werden von Google weniger streng gefiltert als Datacenter-IP-Bereiche.
Ein weiterer Faktor ist der User-Agent-Header. Autocomplete-Calls sollten immer einen realistischen Browser-User-Agent mitsenden, sonst liefert Google leere oder reduzierte Ergebnisse. Die Kombination aus Residential Proxy + korrektem User-Agent + moderatem Rate-Limit (0,3 Sekunden zwischen Anfragen) ist die zuverlässigste Konfiguration.
Praxisbeispiel: Autocomplete und PAA mit Python scrapen
Autocomplete mit httpx und ProxyHat
Der folgende Code zeigt die direkte Proxy-Nutzung mit httpx sowie einen thin Wrapper, der Session-Rotation und Retry-Logik kapselt. Beide Ansätze sind funktional äquivalent – der Wrapper eignet sich für Production-Workloads mit vielen Seeds.
import httpx
import time
import logging
from typing import Optional
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("keyword_scraper")
class ProxyHatSession:
"""Thin wrapper around ProxyHat for session rotation and retries."""
def __init__(self, country: str = "DE", city: Optional[str] = None):
self.gateway = "gate.proxyhat.com:8080"
self.country = country
self.city = city
self._session_id = 0
self._failures = 0
self._circuit_open = False
self._circuit_reset_at = 0.0
def _proxy_url(self) -> str:
self._session_id += 1
user = f"user-country-{self.country}"
if self.city:
user += f"-city-{self.city}"
user += f"-session-s{self._session_id}"
return f"http://{user}:pass@{self.gateway}"
def _check_circuit(self):
if self._circuit_open:
if time.time() < self._circuit_reset_at:
raise RuntimeError("Circuit breaker open — cooling down 60s")
self._circuit_open = False
self._failures = 0
logger.info("Circuit breaker reset")
def request_with_retry(self, fn, max_retries: int = 3):
self._check_circuit()
for attempt in range(max_retries):
proxy = self._proxy_url()
try:
with httpx.Client(proxy=proxy, timeout=15.0) as client:
result = fn(client)
self._failures = 0
return result
except (httpx.HTTPError, httpx.TimeoutException) as exc:
logger.warning(f"Attempt {attempt+1}/{max_retries} failed: {exc}")
self._failures += 1
if self._failures >= 5:
self._circuit_open = True
self._circuit_reset_at = time.time() + 60
logger.error("Circuit breaker opened — 60s cooldown")
raise
time.sleep(2 ** attempt)
return None
# --- Raw proxy usage (einfach) ---
raw_proxy = "http://user-country-DE-city-berlin:pass@gate.proxyhat.com:8080"
with httpx.Client(proxy=raw_proxy) as client:
suggestions = fetch_autocomplete("python webscraping", client)
print(f"Raw proxy: {len(suggestions)} suggestions")
# --- ProxyHat wrapper (production-ready) ---
session = ProxyHatSession(country="DE", city="berlin")
result = session.request_with_retry(lambda c: fetch_autocomplete("python webscraping", c))
if result:
print(f"Wrapper: {len(result)} suggestions")PAA-Akkordeons mit Playwright erweitern
Für PAA-Fragen reicht HTTP nicht aus – die Fragen sind in JavaScript-Akkordeons gerendert und erweitern sich nur bei Klick. Playwright ist die beste Wahl für diese Aufgabe, da es Chromium mit Proxy-Unterstützung steuert und Klicks simulieren kann.
import asyncio
from playwright.async_api import async_playwright
PROXY_CONFIG = {
"server": "http://gate.proxyhat.com:8080",
"username": "user-country-DE-city-berlin",
"password": "pass",
}
async def extract_paa(seed_query: str, max_rounds: int = 5) -> list[dict]:
"""Extract People Also Ask questions and answer sources."""
results = []
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True, proxy=PROXY_CONFIG)
page = await browser.new_page()
url = f"https://www.google.com/search?q={seed_query}&hl=de&gl=de"
await page.goto(url, wait_until="domcontentloaded")
await page.wait_for_selector("div.related-question-pair", timeout=10000)
for round_idx in range(max_rounds):
items = await page.query_selector_all("div.related-question-pair")
# Click up to 3 unexpanded items per round to reveal nested questions
for item in items[:3]:
try:
await item.click()
await page.wait_for_timeout(1500)
except Exception:
continue
questions = await page.evaluate("""
() => {
const nodes = document.querySelectorAll('div.related-question-pair');
return [...nodes].map(n => {
const q = n.querySelector('.CB8E7f')?.textContent?.trim() || '';
const source = n.querySelector('a[href]')?.href || '';
return { question: q, source: source };
}).filter(x => x.question);
}
""")
results.extend(questions)
print(f"Round {round_idx+1}: {len(questions)} questions visible")
await browser.close()
return results
paa_data = asyncio.run(extract_paa("python webscraping", max_rounds=5))
print(f"\nTotal PAA questions extracted: {len(paa_data)}")
for item in paa_data[:10]:
print(f" Q: {item['question']}")
print(f" Source: {item['source']}")Für Related Searches fügen Sie einen ähnlichen Evaluate-Call hinzu, der die Links am Seitenende (#botstuff a oder . related-search) extrahiert. Die Kombination aus Autocomplete + PAA + Related Searches liefert aus einem einzigen Seed-Keyword oft 150–300 einzigartige Keywords.
Deduplizieren, nach Intent clustern und als CSV exportieren
Roh-Keywords aus drei Quellen enthalten viele Duplikate und Near-Duplicates. Der folgende Code entfernt Duplikate, clustert nach Suchintention und exportiert in eine CSV-Datei, die direkt für Content-Planung und FAQ-Generierung nutzbar ist.
import csv
from collections import defaultdict
from difflib import SequenceMatcher
def dedup_keywords(keywords: list[str]) -> list[str]:
"""Remove exact and near-duplicate keywords (>90% similarity)."""
seen = set()
unique = []
for kw in sorted(keywords, key=len):
kw_lower = kw.lower().strip()
if kw_lower in seen:
continue
is_dup = False
for existing in unique:
ratio = SequenceMatcher(None, kw_lower, existing.lower()).ratio()
if ratio > 0.90:
is_dup = True
break
if not is_dup:
seen.add(kw_lower)
unique.append(kw)
return unique
def cluster_by_intent(keywords: list[str]) -> dict[str, list[str]]:
"""Cluster keywords by search intent modifiers."""
intent_map = {
"informational": ["how", "what", "why", "was ist", "wie", "warum", "tipps"],
"transactional": ["buy", "price", "kaufen", "preis", "kosten", "bestellen"],
"navigational": ["login", "download", "anmeldung", "herunterladen"],
"comparison": ["vs", "vergleich", "alternative", "oder", "beste"],
}
clusters = defaultdict(list)
for kw in keywords:
kw_lower = kw.lower()
matched = False
for intent, markers in intent_map.items():
if any(m in kw_lower for m in markers):
clusters[intent].append(kw)
matched = True
break
if not matched:
clusters["general"].append(kw)
return dict(clusters)
def export_to_csv(clusters: dict, filename: str = "keyword_research.csv"):
"""Export keywords with intent clusters to CSV."""
with open(filename, "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["keyword", "intent", "char_length", "word_count"])
for intent, kws in clusters.items():
for kw in kws:
writer.writerow([kw, intent, len(kw), len(kw.split())])
total = sum(len(v) for v in clusters.values())
print(f"Exported {total} keywords to {filename}")
# Usage: combine all sources
all_keywords = list(set(autocomplete_results + [q["question"] for q in paa_data]))
deduped = dedup_keywords(all_keywords)
clusters = cluster_by_intent(deduped)
export_to_csv(clusters)
for intent, kws in clusters.items():
print(f"\n{intent.upper()} ({len(kws)} keywords):")
for kw in kws[:5]:
print(f" {kw}")Eine einzelne Seed-Expansion mit 74 Kombinationen liefert nach Deduplizierung typischerweise 200–300 einzigartige Keywords. Mit 10 Seeds erreichen Sie 1.500–2.500 strukturierte Keywords – ausreichend für ein ganzes Content-Quartal.
Ethik, robots.txt und wann offizielle APIs die bessere Wahl sind
Autocomplete-Vorschläge und PAA-Fragen sind öffentlich sichtbare Daten, die jeder Browser-Nutzer sieht. Dennoch gibt es ethische und technische Grenzen:
- Rate-Limiting: Halten Sie mindestens 0,3 Sekunden Abstand zwischen Anfragen. Bei 100+ Anfragen pro Sekunde riskieren Sie IP-Sperren und beeinträchtigen die Service-Qualität für andere.
- robots.txt respektieren: Prüfen Sie robots.txt-Richtlinien für die Zielseiten. Autocomplete und SERPs haben eigene Regeln – Google erlaubt den Suggest-Endpunkt nicht explizit in robots.txt, aber die SERP-Seite ist für Crawler gesperrt.
- Skalierung: Für >10.000 Keywords pro Tag sollten Sie offizielle APIs wie die Google Custom Search API oder kommerzielle Keyword-Tools in Betracht ziehen. Scraping ist ideal für Prototypen und mittelgroße Keyword-Sets.
- Datenschutz: PAA-Antwortquellen können personenbezogene Daten enthalten. Beim Export in CSV oder Datenbanken sollten Sie URLs auf ihre Domain reduzieren, wenn Sie die Daten weitergeben.
Residential Proxies machen Scraping technisch möglich, aber sie ersetzen nicht den gesunden Menschenverstand. Wenn Sie eine Keyword-Recherche-Pipeline bauen, die täglich läuft, kombinieren Sie Proxies mit Backoff-Strategien und überwachen Sie die Fehlerrate. Eine 99,9 % Success Rate mit 200 ms Latenz pro Anfrage ist realistisch – aber nur, wenn Sie nicht gierig werden.
Production-Tipp: Logging ist nicht optional. Protokollieren Sie jede Anfrage mit Seed, Proxy-Session-ID, Response-Status und Timestamp. Wenn Google plötzlich leere Antworten liefert, sehen Sie sofort, welche Session betroffen ist und können gezielt rotieren.
ProxyHat bietet Residential Proxies mit Geo-Targeting auf Länder- und Stadtebene – ideal für lokalisierte Autocomplete-Ergebnisse. Die Preise sind transparent und skalieren mit Ihrem Bedarf. Weitere Details finden Sie in der ProxyHat-Dokumentation.
Key Takeaways
- Drei Quellen kombinieren: Autocomplete (Long-Tail), PAA (Frage-Intent) und Related Searches (semantische Cluster) ergänzen sich und liefern 150–300 Keywords pro Seed.
- Seed-Expansion mit a-z und Modifiern: Aus einem Keyword werden 74+ Kombinationen, die jeweils 10 Vorschlägen zurückgeben – das ist die Hebelwirkung, die Ihren Keyword-Pool vervielfacht.
- Residential Proxies sind Pflicht: Datacenter-IPs werden von Google schnell erkannt. Geo-Targeting (
user-country-DE-city-berlin) sorgt für lokal korrekte Vorschläge. - Playwright für PAA: HTTP reicht für Autocomplete, aber PAA-Akkordeons brauchen einen echten Browser-Kontext mit Klick-Simulation.
- Dedup + Intent-Clustering: Near-Duplicate-Erkennung (>90 % Ähnlichkeit) und Intent-Gruppen (informational, transaktional, Vergleich) machen die Rohdaten direkt für Content-Planung nutzbar.
- Ethisch scrapen: 0,3 Sekunden Delay, Circuit Breaker nach 5 Fehlern, robots.txt respektieren und bei Skalierung offizielle APIs evaluieren.
Bereit, Ihre eigene Keyword-Research-Pipeline zu bauen? Starten Sie mit Web-Scraping mit ProxyHat oder erkunden Sie verfügbare Proxy-Standorte. Für SERP-Tracking im größeren Maßstab siehe unsere SERP-Tracking-Anwendungsfälle.




