Raspar People Also Ask e Autocomplete do Google para Pesquisa de Palavras-chave (Guia Python)

Guia prático para desenvolvedores e SEOs sobre como raspar Autocomplete, PAA e Related Searches do Google com Python, httpx e proxies residenciais geo-direcionados.

Scrape Google People Also Ask and Autocomplete for Keyword Research (Python Guide)
Neste artigo

Pesquisa de palavras-chave virou um jogo de volume e intenção: uma única semente como “seguro de viagem” pode gerar 300+ variações longtail se você souber onde procurar. Este guia mostra como raspar People Also Ask e Autocomplete do Google com Python, combinando o endpoint público de sugestões, o bloco PAA e Related Searches. Vamos usar httpx para chamadas concorrentes, Playwright para expandir acordeões de PAA e proxies residenciais geo-direcionados para obter sugestões localizadas sem disparar limites de taxa por IP.

O Google expõe três fontes públicas de intenção de busca, cada uma mapeando para um estágio diferente do funnel de pesquisa:

FonteEndpoint / seletorIntenção dominanteVolume típico por semente
Autocomplete (Suggest)suggestqueries.google.com/complete/search?client=chrome&q=Longtail informacional e transacional10 sugestões por letra/modificador
People Also AskSeletor div.related-question-pair na SERPPerguntas informacionais (5W1H)4-8 iniciais, expansível recursivamente
Related SearchesSeletor div.brs-col no fim da SERPVariações semânticas e comerciais8-10 por consulta

O endpoint de Autocomplete é o mais produtivo em volume: cada letra do alfabeto (a-z) mais modificadores (“como”, “melhor”, “preço”) gera ~10 sugestões, totalizando 260+ variações a partir de uma semente. O PAA é mais rico em intenção pergunta e expande recursivamente — cada pergunta clicada revela 2-3 novas perguntas aninhadas, conforme documentado em estudos de interação com acordeões web. Related Searches fecha o ciclo com variações semânticas que o Google já agrupou como relevantes.

Mapeando cada fonte para intenção de busca

  • Autocomplete → longtail de cauda longa, ótimo para páginas de produto e guias de compra.
  • PAA → perguntas para FAQ, schema FAQPage e conteúdo de topo de funil.
  • Related Searches → variações de cluster temático para silo de conteúdo.

Construindo um expansor semente-para-longtail

A estratégia é simples mas poderosa: pegue uma semente, adicione prefixos alfabéticos (a-z) e modificadores de intenção, consulte o endpoint de autocomplete para cada combinação e dedupe os resultados. Com 26 letras + 5 modificadores = 31 chamadas por semente, gerando ~300 sugestões brutas.

Exemplo 1: Expansor de autocomplete com httpx e ProxyHat

import httpx
import asyncio
import itertools
import json
from urllib.parse import quote

PROXY_URL = "http://user-country-DE-city-berlin:pass@gate.proxyhat.com:8080"
SUGGEST_URL = "https://suggestqueries.google.com/complete/search?client=chrome&q={q}"

async def fetch_suggestions(client: httpx.AsyncClient, query: str) -> list[str]:
    url = SUGGEST_URL.format(q=quote(query))
    try:
        resp = await client.get(url, timeout=10.0)
        resp.raise_for_status()
        data = resp.json()
        # data[1] contém a lista de sugestões
        return data[1] if len(data) > 1 else []
    except (httpx.HTTPError, json.JSONDecodeError) as exc:
        print(f"Erro para '{query}': {exc}")
        return []

async def expand_seed(seed: str) -> set[str]:
    modifiers = ["", "como ", "melhor ", "preço ", "vs "]
    prefixes = list(itertools.chain(modifiers, [chr(c) + " " for c in range(ord("a"), ord("z") + 1)]))
    queries = [f"{p}{seed}" for p in prefixes]

    async with httpx.AsyncClient(
        proxy=PROXY_URL,
        headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"},
        limits=httpx.Limits(max_connections=5),
    ) as client:
        tasks = [fetch_suggestions(client, q) for q in queries]
        results = await asyncio.gather(*tasks)

    all_suggestions = set()
    for query, suggestions in zip(queries, results):
        for s in suggestions:
            all_suggestions.add(s)
    return all_suggestions

if __name__ == "__main__":
    seed = "seguro de viagem"
    suggestions = asyncio.run(expand_seed(seed))
    print(f"{len(suggestions)} sugestões únicas para '{seed}'")
    for s in sorted(suggestions)[:10]:
        print(f"  - {s}")

Esse script faz 31 chamadas concorrentes (limitadas a 5 conexões simultâneas) via proxy residencial em Berlim, retornando sugestões localizadas para o mercado alemão. Sem geo-targeting, o Google retornaria sugestões baseadas no IP do servidor — provavelmente EUA ou Irlanda se você usa um cloud provider.

Expansão recursiva de PAA com Playwright

O bloco People Also Ask começa com 4-8 perguntas, mas cada acordeão clicado revela mais 2-3 perguntas aninhadas. Expandir recursivamente pode gerar 50-100 perguntas por semente. Como o PAA é renderizado dinamicamente e requer clique, usamos Playwright com proxy.

Exemplo 2: Extrator de PAA com Playwright e proxy SOCKS5

from playwright.async_api import async_playwright
import asyncio
import json

SOCKS5_PROXY = "socks5://user-country-US:pass@gate.proxyhat.com:1080"

async def scrape_paa(seed: str, max_depth: int = 3) -> list[dict]:
    questions = []
    seen = set()

    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=True,
            proxy={"server": SOCKS5_PROXY},
        )
        context = await browser.new_context(
            user_agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
            viewport={"width": 1280, "height": 800},
        )
        page = await context.new_page()
        await page.goto(f"https://www.google.com/search?q={seed}", wait_until="domcontentloaded")

        for depth in range(max_depth):
            paa_elements = await page.query_selector_all("div.related-question-pair")
            for el in paa_elements:
                text = await el.inner_text()
                question_text = text.strip().split("\n")[0]
                if question_text and question_text not in seen:
                    seen.add(question_text)
                    questions.append({
                        "question": question_text,
                        "depth": depth,
                        "seed": seed,
                    })
                    # Clica para expandir e revelar perguntas aninhadas
                    try:
                        await el.click(timeout=2000)
                        await page.wait_for_timeout(800)
                    except Exception:
                        continue

        await browser.close()
    return questions

if __name__ == "__main__":
    results = asyncio.run(scrape_paa("seguro de viagem europeu"))
    print(json.dumps(results[:5], ensure_ascii=False, indent=2))

Exemplo 3: Extraindo fontes citadas nas respostas de PAA

Cada resposta expandida de PAA inclui links de fonte citados pelo Google. Esses domínios são oportunidades de backlink e indicam quais sites o Google considera autoritativos para o tópico.

async def extract_paa_with_sources(page, seed: str) -> list[dict]:
    results = []
    paa_blocks = await page.query_selector_all("div.related-question-pair")
    for block in paa_blocks[:8]:
        try:
            await block.click(timeout=3000)
            await page.wait_for_timeout(1000)

            question = (await block.inner_text()).strip().split("\n")[0]

            # Extrai links de fonte dentro do bloco expandido
            source_links = await block.query_selector_all("a[data-ved]")
            sources = []
            for link in source_links:
                href = await link.get_attribute("href")
                text = await link.inner_text()
                if href and href.startswith("http"):
                    sources.append({"url": href, "anchor": text.strip()})

            results.append({
                "question": question,
                "seed": seed,
                "sources": sources[:3],  # top 3 fontes citadas
            })
        except Exception as exc:
            print(f"Erro ao expandir bloco: {exc}")
            continue
    return results

Por que chamadas rápidas disparam limites de taxa e viés de localização

O Google aplica dois mecanismos de defesa que afetam scraping de autocomplete e PAA:

  1. Limite de taxa por IP: chamadas acima de ~100/min do mesmo IP retornam HTTP 429 ou redirecionam para CAPTCHA. O endpoint de autocomplete é mais tolerante que a SERP HTML, mas ainda assim bloqueia IPs datacenter agressivamente.
  2. Viés de localização: sugestões de autocomplete e resultados de PAA são influenciados pelo país e cidade do IP solicitante. Um request de um IP em Frankfurt retorna sugestões em alemão; o mesmo query de um IP em São Paulo retorna sugestões em português brasileiro.

Proxies datacenter (AWS, DigitalOcean, OVH) são rapidamente identificados pelo Google porque seus ranges de IP são publicamente conhecidos. Proxies residenciais usam IPs atribuídos a dispositivos reais por ISPs, tornando a detecção muito mais difícil. Combine isso com geo-targeting de país e cidade para obter sugestões consistentes para um mercado-alvo.

Exemplo 4: Rotação de sessões sticky por país com ProxyHat

import httpx
import asyncio
import random
import string

BASE_PROXY = "http://gate.proxyhat.com:8080"

def make_proxy_url(country: str, city: str = None) -> str:
    session_id = "".join(random.choices(string.ascii_lowercase + string.digits, k=8))
    username = f"user-country-{country}-session-{session_id}"
    if city:
        username = f"user-country-{country}-city-{city}-session-{session_id}"
    return f"http://{username}:pass@gate.proxyhat.com:8080"

async def fetch_with_retry(client_factory, url: str, max_retries: int = 3) -> dict:
    for attempt in range(max_retries):
        proxy_url = make_proxy_url("BR", "saopaulo")
        async with httpx.AsyncClient(
            proxy=proxy_url,
            headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"},
            timeout=15.0,
        ) as client:
            try:
                resp = await client.get(url)
                if resp.status_code == 200:
                    return resp.json()
                elif resp.status_code == 429:
                    wait = 2 ** attempt + random.uniform(0.5, 1.5)
                    print(f"429 recebido, esperando {wait:.1f}s")
                    await asyncio.sleep(wait)
                    continue
                else:
                    print(f"HTTP {resp.status_code}")
                    return {}
            except httpx.HTTPError as exc:
                print(f"Tentativa {attempt+1} falhou: {exc}")
                await asyncio.sleep(2 ** attempt)
    return {}

async def main():
    url = "https://suggestqueries.google.com/complete/search?client=chrome&q=seguro%20viagem"
    data = await fetch_with_retry(None, url)
    suggestions = data.get("1", []) if isinstance(data, list) and len(data) > 1 else []
    print(f"{len(suggestions)} sugestões via proxy BR/São Paulo")

asyncio.run(main())

O parâmetro -session- mantém o mesmo IP residencial por sessão, útil para manter consistência de localização entre chamadas relacionadas. Sem session, cada request recebe um novo IP automaticamente.

Dedup, clusterização por intenção e exportação para CSV

Após coletar sugestões de autocomplete, perguntas de PAA e Related Searches, você terá centenas de termos sobrepostos. O próximo passo é limpar, clusterizar por intenção e exportar para planejamento de conteúdo.

Exemplo 5: Pipeline completo de dedup, clusterização e exportação CSV

import csv
import re
from collections import defaultdict

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

def classify_intent(kw: str) -> str:
    informational = ["como", "o que é", "por que", "quando", "qual", "guia", "tutorial"]
    commercial = ["melhor", "top", "comparativo", "review", "vs"]
    transactional = ["comprar", "preço", "desconto", "barato", "oferta"]
    kw_lower = kw.lower()
    if any(w in kw_lower for w in transactional):
        return "transactional"
    if any(w in kw_lower for w in commercial):
        return "commercial"
    if any(w in kw_lower for w in informational):
        return "informational"
    return "navigational"

def dedupe_and_cluster(all_keywords: list[str]) -> dict[str, list[str]]:
    seen = set()
    clusters = defaultdict(list)
    for kw in all_keywords:
        norm = normalize_keyword(kw)
        if norm not in seen and len(norm) > 3:
            seen.add(norm)
            intent = classify_intent(norm)
            clusters[intent].append(norm)
    return clusters

def export_to_csv(clusters: dict[str, list[str]], filename: str = "keywords.csv"):
    with open(filename, "w", newline="", encoding="utf-8") as f:
        writer = csv.writer(f)
        writer.writerow(["keyword", "intent", "source"])
        for intent, keywords in clusters.items():
            for kw in keywords:
                writer.writerow([kw, intent, "google-suggest+paa"])
    print(f"{sum(len(v) for v in clusters.values())} palavras-chave exportadas para {filename}")

# Uso
if __name__ == "__main__":
    raw_keywords = [
        "seguro de viagem europeu",
        "como funciona seguro de viagem",
        "melhor seguro de viagem internacional",
        "seguro de viagem preço",
        "o que é seguro de viagem",
        "comprar seguro de viagem online",
        "seguro de viagem vs plano de saúde",
    ]
    clusters = dedupe_and_cluster(raw_keywords)
    export_to_csv(clusters)

Esse pipeline normaliza keywords (remove espaços extras, lowercase), classifica intenção usando padrões linguísticos e agrupa em clusters. O CSV resultante alimenta diretamente um calendário editorial: perguntas viram FAQ pages, termos transacionais viram landing pages de produto, e termos informacionais viram artigos de blog.

Configuração do ProxyHat e melhores práticas de produção

Para integrar o ProxyHat no seu pipeline de keyword research, configure o gateway residencial com geo-targeting. A documentação completa está em docs.proxyhat.com.

Configuração recomendada

ParâmetroValorQuando usar
Gatewaygate.proxyhat.com:8080HTTP/HTTPS (autocomplete, SERP)
SOCKS5gate.proxyhat.com:1080Playwright, navegadores headless
Geo-targeting-country-BR-city-saopauloSugestões localizadas por mercado
Session sticky-session-abc123Manter IP consistente entre chamadas
Concorrência5-10 por IPEvitar 429 e CAPTCHA

Exemplo: curl com geo-targeting para validar localização

curl -x "http://user-country-DE-city-berlin:pass@gate.proxyhat.com:8080" \
  "https://suggestqueries.google.com/complete/search?client=chrome&q=versicherung" \
  -H "User-Agent: Mozilla/5.0" \
  --max-time 10

Confira os locais de proxy disponíveis e a página de preços para escolher o plano adequado ao seu volume de scraping.

Erros comuns e casos de borda

  • Esquecer headers de navegador: o endpoint de autocomplete retorna JSON mesmo sem headers, mas a SERP HTML requer um User-Agent realista. Sem ele, o Google retorna uma página simplificada sem PAA.
  • Concorrência excessiva: mais de 10 conexões simultâneas por IP residencial aumenta drasticamente a taxa de 429. Use httpx.Limits(max_connections=5) como padrão.
  • Ignorar parâmetro client: client=chrome retorna JSON estruturado; client=firefox retorna formato diferente; sem client, retorna XML. Sempre use client=chrome.
  • Não dedupar entre fontes: PAA e Related Searches frequentemente sobrepõem. Normalize e dedupe antes de exportar.
  • Parar na primeira camada de PAA: o valor real está na recursão. Cada clique revela 2-3 novas perguntas. Configure max_depth=3 no mínimo.

Ética e considerações legais

Autocomplete, PAA e Related Searches são dados públicos exibidos pelo Google para qualquer usuário. Raspar esses dados para pesquisa de palavras-chave é amplamente aceito, mas há limites:

  • Respeite robots.txt: verifique as regras de suggestqueries.google.com/robots.txt antes de coletar em escala.
  • Throttle polite: mantenha 1-3 segundos de delay aleatório entre chamadas. Não é apenas ético — reduz bloqueios.
  • Prefira APIs oficiais em escala: o Google Custom Search JSON API e o Google Search Console fornecem dados de query oficiais com limites documentados. Para volumes acima de 10.000 queries/dia, migre para APIs oficiais.
  • GDPR e dados pessoais: sugestões de autocomplete podem conter nomes de pessoas. Não armazene nem processe dados pessoais sem base legal.

Para casos de uso de scraping web e SERP tracking em produção, consulte nossos guias de web scraping e SERP tracking.

Dica de produção: implemente um circuit breaker que pausa o scraping por 60 segundos após 3 erros 429 consecutivos. Isso evita que o Google marque seu pool de proxies como abusivo e estenda o bloqueio para além do IP individual.

Key Takeaways

  • Autocomplete é a fonte de maior volume: 31 combinações (a-z + modificadores) geram ~300 sugestões por semente.
  • PAA é a fonte de maior intenção pergunta: expansão recursiva com Playwright revela 50-100 perguntas por semente, com fontes citadas.
  • Related Searches fecha o cluster temático: use junto com PAA para mapear o ecossistema semântico de um tópico.
  • Proxies residenciais com geo-targeting são obrigatórios: sem country/city targeting, sugestões são enviesadas pelo IP do servidor e chamadas rápidas disparam 429.
  • Dedupe e clusterize por intenção antes de exportar: classifica em informational, commercial, transactional e navigational para alimentar um calendário editorial.
  • Em escala, prefira APIs oficiais: Google Custom Search API e Search Console são mais sustentáveis acima de 10.000 queries/dia.

FAQ

O que é raspar People Also Ask e Autocomplete do Google?

É o processo de coletar automaticamente sugestões de autocomplete, perguntas do bloco People Also Ask e buscas relacionadas da página de resultados do Google, usando scripts Python e clientes HTTP. Esses dados revelam intenções de busca reais e permitem expandir uma palavra-chave semente em centenas de variações longtail para planejamento de conteúdo e FAQ.

Por que raspar PAA e Autocomplete importa para usuários de proxy?

O Google impõe limites de taxa por IP e aplica viés de localização nas sugestões. Sem proxies residenciais geo-direcionados, chamadas rápidas a endpoints de autocomplete e PAA retornam erros 429, CAPTCHAs ou sugestões enviesadas pelo IP do servidor. Proxies residenciais com country/city targeting permitem obter sugestões limpas e localizadas a escala.

Qual tipo de proxy funciona melhor para raspar PAA e Autocomplete?

Proxies residenciais são os mais adequados porque usam IPs de dispositivos reais atribuídos por ISPs, reduzindo a chance de bloqueio. Para sugestões localizadas, combine geo-targeting de país e cidade no usuário do proxy. Proxies datacenter são mais baratos, mas têm maior taxa de bloqueio em endpoints do Google.

Como evitar bloqueios ao raspar People Also Ask e Autocomplete?

Use proxies residenciais com rotação por requisição, limite a concorrência a 5-10 conexões simultâneas por IP, adicione delays aleatórios de 1-3 segundos entre chamadas, configure headers realistas de navegador e implemente retentativas com backoff exponencial. Em escala, prefira a Official Google Suggest API ou Search Console.

Perguntas frequentes

O que é raspar People Also Ask e Autocomplete do Google?

É o processo de coletar automaticamente sugestões de autocomplete, perguntas do bloco People Also Ask e buscas relacionadas da página de resultados do Google, usando scripts Python e clientes HTTP. Esses dados revelam intenções de busca reais e permitem expandir uma palavra-chave semente em centenas de variações longtail para planejamento de conteúdo e FAQ.

Por que raspar PAA e Autocomplete importa para usuários de proxy?

O Google impõe limites de taxa por IP e aplica viés de localização nas sugestões. Sem proxies residenciais geo-direcionados, chamadas rápidas a endpoints de autocomplete e PAA retornam erros 429, CAPTCHAs ou sugestões enviesadas pelo IP do servidor. Proxies residenciais com country/city targeting permitem obter sugestões limpas e localizadas a escala.

Qual tipo de proxy funciona melhor para raspar PAA e Autocomplete?

Proxies residenciais são os mais adequados porque usam IPs de dispositivos reais atribuídos por ISPs, reduzindo a chance de bloqueio. Para sugestões localizadas, combine geo-targeting de país e cidade no usuário do proxy. Proxies datacenter são mais baratos, mas têm maior taxa de bloqueio em endpoints do Google.

Como evitar bloqueios ao raspar People Also Ask e Autocomplete?

Use proxies residenciais com rotação por requisição, limite a concorrência a 5-10 conexões simultâneas por IP, adicione delays aleatórios de 1-3 segundos entre chamadas, configure headers realistas de navegador e implemente retentativas com backoff exponencial. Em escala, prefira a Official Google Suggest API ou Search Console.

Pronto para começar?

Proxies residenciais, ISP e móveis em mais de 148 países. Crie uma conta grátis.

Criar conta grátis
← Voltar ao Blog