Google People Also Ask ve Autocomplete Verilerini Kazımak: Python Rehberi

Google Autocomplete, People Also Ask ve Related Searches verilerini residential proxy ile kazıyarak uzun kuyruklu anahtar kelime fırsatları yaratın. Python, httpx ve Playwright ile çalışan örnekler.

Scrape Google People Also Ask and Autocomplete for Keyword Research (Python Guide)
Bu makalede

Google People Also Ask ve Autocomplete Kazıma Nedir?

Google People Also Ask (PAA) ve Autocomplete verilerini kazımak, SEO uzmanları ve geliştiriciler için en verimli ücretsiz anahtar kelime araştırma yöntemlerinden biridir. Üç temel veri kaynağı vardır: Autocomplete öneri endpoint'i, PAA soruları ve Related Searches. Bu rehberde her birini Python ile nasıl kazıyacağınızı, residential proxy'lerle nasıl lokalize edeceğinizi ve sonuçları nasıl kümeleyeceğinizi göstereceğiz.

Bu yöntemler, Google'ın resmi Custom Search API'sinden farklı olarak tamamen ücretsizdir ve gerçek kullanıcı sorgularını yansıtır. Ancak ölçeklendirildiğinde IP tabanlı hız sınırlarına takılır; bu yüzden residential proxy kullanımı kritik hale gelir.

Üç Ücretsiz Anahtar Kelime Altın Madeni

Google'ın arama sonuç sayfasında ve tarayıcı arama kutusunda üç farklı öneri mekanizması çalışır. Her biri farklı bir arama niyetini (search intent) temsil eder:

1. Autocomplete (Suggest) Endpoint

Google'ın Autocomplete servisi, suggestqueries.google.com/complete/search?client=chrome&q= adresine JSON döndürür. Bu endpoint, tarayıcı arama kutusuna yazılan her harfle birlikte gerçek zamanlı öneriler üretir. Kullanıcılar daha aramayı tamamlamadan ne yazacaklarını düşünür; bu yüzden bilgi arama (informational intent) yoğunludur.

Örnek: q="keto diyet" için dönen öneriler genellikle keto diyet nedir, keto diyet listesi, keto diyet zararları gibi soru kalıplarıdır.

2. People Also Ask (PAA)

PAA kutuları, arama sonuçlarında görünen ve tıklandıkça iç içe geçen soru akordeonlarıdır. Her soru genellikle bir karşılaştırma veya derinlemesine bilgi arama niyetini yansıtır. Bir PAA sorusunu tıkladığınızda Google yeni sorular yükler; bu recursive expansion olarak bilinir ve tek bir anahtar kelimeden onlarca soru çıkarabilir.

Sayfanın en altında yer alan Related Searches, aramayı tamamlamış kullanıcıların sonraki adımlarını gösterir. Transactional ve navigational intent yoğunludur; örneğin keto diyet kitabı satın al gibi.

KaynakDominant IntentFormatVeri Çekme Zorluğu
AutocompleteInformationalJSON (client=chrome)Düşük
People Also AskInformational + ComparisonHTML (accordion)Orta-Yüksek
Related SearchesTransactionalHTMLDüşük

Teknik Bağlam: Neden Bu Problem Var?

Google'ın öneri sistemleri, arama kutusuna her tuş basışında gerçek zamanlı olarak çalışır. Bu, tek bir IP'den saniyede onlarca istek gönderdiğinizde Google'ın bot korumasını tetikler. HTTP 429 Too Many Requests yanıtı veya CAPTCHA sayfası alırsınız.

Ayrıca Autocomplete önerileri, isteğin geldiği IP'nin coğrafi konumuna göre değişir. Berlin'den yapılan bir arama ile İstanbul'dan yapılan arama farklı öneriler döndürür. Bu locale bias, doğru lokalize veri toplamak için residential proxy'leri zorunlu kılar.

Veri merkezi (datacenter) IP'leri Google tarafından kolayca işaretlenir ve bloke edilir. SERP takibi ve öneri kazıma gibi işlemlerde residential proxy'ler çok daha yüksek başarı oranı sağlar; tipik olarak %90+ başarı oranına karşı datacenter proxy'lerde %30-50 civarı.

ProxyHat ile Residential Proxy Kurulumu

ProxyHat residential proxy'leri, ülke ve şehir seviyesinde geo-targeting destekler. Kullanıcı adı içinde bayraklar ile lokasyon belirlenir. Örneğin Berlin'den gelen istekler için:

# HTTP proxy URL formatı
http://user-country-DE-city-berlin:pass@gate.proxyhat.com:8080

# SOCKS5 proxy URL formatı
socks5://user-country-DE-city-berlin:pass@gate.proxyhat.com:1080

# Sticky session (aynı IP'de kal)
http://user-country-DE-city-berlin-session-abc123:pass@gate.proxyhat.com:8080

Mevcut lokasyonlar sayfasından desteklenen ülkeleri ve şehirleri görebilirsiniz. Autocomplete kazıma için her ülke için ayrı oturum açmak, o bölgeye özel önerileri yakalamanın en iyi yoludur.

Python ile Autocomplete Kazıma: httpx + ProxyHat

Aşağıdaki örnek, bir seed kelimeyi a-z harfleri ve yaygın modifier'larla genişleterek yüzlerce uzun kuyruklu öneri üretir. httpx ile asenkron istekler gönderir ve ProxyHat residential proxy'lerini kullanır.

import httpx
import asyncio
import json
import logging
from typing import List, Set

# Logging konfigürasyonu
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
logger = logging.getLogger(__name__)

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

# Hata yeniden deneme decorator benzeri fonksiyon
async def fetch_with_retry(client: httpx.AsyncClient, params: dict, max_retries: int = 3) -> dict:
    for attempt in range(max_retries):
        try:
            response = await client.get(AUTOCOMPLETE_URL, params=params, timeout=10.0)
            if response.status_code == 200:
                return response.json()
            elif response.status_code == 429:
                wait = 2 ** attempt
                logger.warning(f"Rate limited, waiting {wait}s...")
                await asyncio.sleep(wait)
            else:
                logger.error(f"HTTP {response.status_code}")
                break
        except httpx.RequestError as e:
            logger.error(f"Request error: {e}")
            await asyncio.sleep(1)
    return {}

async def get_autocomplete_suggestions(keyword: str, client: httpx.AsyncClient) -> List[str]:
    params = {
        "client": "chrome",
        "q": keyword,
        "hl": "de",  # dil parametresi
        "gl": "de"   # ülke parametresi
    }
    data = await fetch_with_retry(client, params)
    # Chrome client JSON formatı: ["query", ["sug1", "sug2", ...], ...]
    if data and len(data) > 1:
        return data[1]
    return []

def build_expanded_seeds(base_keyword: str) -> List[str]:
    seeds = [base_keyword]
    # a-z harf genişletme
    for c in "abcdefghijklmnopqrstuvwxyz":
        seeds.append(f"{base_keyword} {c}")
    # Modifier prefix'leri
    modifiers = ["nedir", "nasıl", "neden", "fiyat", "ücretsiz", "en iyi", "2024", "vs"]
    for m in modifiers:
        seeds.append(f"{base_keyword} {m}")
        seeds.append(f"{m} {base_keyword}")
    return seeds

async def expand_keyword(base_keyword: str) -> Set[str]:
    seeds = build_expanded_seeds(base_keyword)
    all_suggestions = set()
    
    async with httpx.AsyncClient(proxy=PROXY_URL) as client:
        # Semalt-style batch processing with concurrency limit
        semaphore = asyncio.Semaphore(5)  # Aynı anda en fazla 5 istek
        
        async def process_seed(seed: str):
            async with semaphore:
                suggestions = await get_autocomplete_suggestions(seed, client)
                for s in suggestions:
                    all_suggestions.add(s)
                logger.info(f"Seed: {seed} -> {len(suggestions)} suggestions")
                await asyncio.sleep(0.5)  # Polite delay
        
        await asyncio.gather(*[process_seed(s) for s in seeds])
    
    return all_suggestions

# Çalıştırma
if __name__ == "__main__":
    results = asyncio.run(expand_keyword("keto diyet"))
    print(f"Toplam {len(results)} benzersiz öneri bulundu")
    for r in sorted(results)[:20]:
        print(f"  - {r}")

Bu kod tek bir seed kelimeden ~300-500 öneri üretebilir. Concurrency'yi 5'te tutmak ve her istekler arası 500ms bekleme, Google'ın rate limit'lerini tetiklememek için kritiktir.

Playwright ile PAA Akordeonlarını Genişletme

PAA soruları, sayfa yüklendiğinde sadece ilk 3-4 sorunu gösterir. Geri kalanlar, bir soruya tıklandığında dinamik olarak yüklenir. Bu recursive expansion için headless browser gerekir. Playwright Python bu iş için idealdir.

import asyncio
from playwright.async_api import async_playwright
import json
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

PROXY_SERVER = "gate.proxyhat.com:8080"
PROXY_USER = "user-country-DE-city-berlin"
PROXY_PASS = "PASSWORD"

async def scrape_paa(keyword: str, max_clicks: int = 10) -> list:
    paa_questions = []
    
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=True,
            proxy={
                "server": f"http://{PROXY_SERVER}",
                "username": PROXY_USER,
                "password": PROXY_PASS
            }
        )
        context = await browser.new_context(
            locale="de-DE",
            viewport={"width": 1920, "height": 1080}
        )
        page = await context.new_page()
        
        url = f"https://www.google.com/search?q={keyword}&hl=de&gl=de"
        await page.goto(url, wait_until="domcontentloaded")
        
        # PAA bloklarını bul
        paa_selector = "div[jsname] div.related-question-pair"
        
        for click_count in range(max_clicks):
            try:
                # Görünür PAA sorularını topla
                questions = await page.query_selector_all(paa_selector)
                for q in questions:
                    text = await q.inner_text()
                    if text and text.endswith("?") and text not in paa_questions:
                        paa_questions.append(text)
                        logger.info(f"PAA: {text}")
                
                # İlk tıklanmamış PAA akordeonunu tıkla
                accordion = await page.query_selector("div[jsname='Cpkphb']")
                if accordion:
                    await accordion.click()
                    await page.wait_for_timeout(1500)  # Dinamik içerik için bekle
                else:
                    logger.info("Daha fazla akordeon bulunamadı")
                    break
            except Exception as e:
                logger.error(f"Tıklama hatası: {e}")
                break
        
        await browser.close()
    
    return paa_questions

# Çalıştırma
if __name__ == "__main__":
    questions = asyncio.run(scrape_paa("keto diyet", max_clicks=15))
    print(f"\nToplam {len(questions)} PAA sorusu bulundu:")
    for q in questions:
        print(f"  - {q}")

PAA Sorularından Yanıt Kaynaklarını Çıkarma

PAA sorularının her birinin bir kaynak linki vardır. Bu linkleri de çıkararak içerik planlamada kullanabileceğiniz rakip kaynakları tespit edebilirsiniz:

async def scrape_paa_with_sources(keyword: str, max_clicks: int = 10) -> list:
    results = []
    
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=True,
            proxy={
                "server": f"http://{PROXY_SERVER}",
                "username": PROXY_USER,
                "password": PROXY_PASS
            }
        )
        context = await browser.new_context(locale="de-DE")
        page = await context.new_page()
        
        await page.goto(f"https://www.google.com/search?q={keyword}&hl=de&gl=de")
        await page.wait_for_timeout(2000)
        
        # PAA sorularını ve kaynak linklerini çıkar
        paa_blocks = await page.query_selector_all("div.related-question-pair")
        for block in paa_blocks:
            question_el = await block.query_selector("div.Cc5ZCb span")
            source_el = await block.query_selector("a[href]")
            
            question = await question_el.inner_text() if question_el else ""
            source_url = await source_el.get_attribute("href") if source_el else ""
            source_text = await source_el.inner_text() if source_el else ""
            
            if question:
                results.append({
                    "question": question,
                    "source_url": source_url,
                    "source_domain": source_text
                })
        
        await browser.close()
    
    return results

Related Searches, sayfanın en altında basit HTML olarak gelir. Proxy ile birlikte curl kullanarak hızlıca çıkarabilirsiniz:

import httpx
import asyncio
from bs4 import BeautifulSoup
import re

PROXY_URL = "http://user-country-DE-city-berlin:PASSWORD@gate.proxyhat.com:8080"

async def get_related_searches(keyword: str) -> list[str]:
    url = f"https://www.google.com/search?q={keyword}&hl=de&gl=de"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
        "Accept-Language": "de-DE,de;q=0.9"
    }
    
    async with httpx.AsyncClient(proxy=PROXY_URL, headers=headers) as client:
        resp = await client.get(url, timeout=15.0)
        if resp.status_code != 200:
            return []
        
        soup = BeautifulSoup(resp.text, "html.parser")
        related = []
        # Related searches linkleri p.bhDWb sınıfında bulunur
        for a in soup.select("a"):  
            href = a.get("href", "")
            if "/search?q=" in href and "spell=" not in href:
                text = a.get_text(strip=True)
                if text and len(text) > 3:
                    related.append(text)
        return list(set(related))

# curl ile manuel test:
# curl -x http://user-country-DE-city-berlin:PASSWORD@gate.proxyhat.com:8080 \
#   "https://www.google.com/search?q=keto+diyet&hl=de&gl=de" \
#   -H "User-Agent: Mozilla/5.0" -H "Accept-Language: de-DE"

Dedup, Intent Kümeleme ve CSV Dışa Aktarma

Üç kaynaktan gelen verileri birleştirip intent'e göre kümelemek, içerik takvimini planlamanın anahtarıdır. Aşağıdaki kod, tüm önerileri toplar, tekrarları kaldırır ve basit kural tabanlı intent sınıflaması yapar:

import csv
import re
from collections import defaultdict

def classify_intent(query: str) -> str:
    q = query.lower()
    # Informational
    if any(w in q for w in ["nedir", "nasıl", "neden", "kim", "ne zaman", "ne demek"]):
        return "informational"
    # Transactional
    if any(w in q for w in ["satın al", "fiyat", "ücret", "indirim", "kampanya", "bedava"]):
        return "transactional"
    # Commercial investigation
    if any(w in q for w in ["en iyi", "karşılaştır", "vs", "hangi", "review", "yorum"]):
        return "commercial"
    # Navigational
navigational if any(w in q for w in ["giriş", "kaydol", "resmi site", "login"]):
        return "navigational"
    return "other"

def cluster_by_topic(queries: list[str]) -> dict:
    clusters = defaultdict(list)
    for q in queries:
        # İlk 2 kelimeyi topic key olarak kullan
        words = q.split()[:2]
        topic = " ".join(words) if len(words) >= 2 else q
        clusters[topic].append(q)
    return dict(clusters)

def export_to_csv(all_queries: set[str], filename: str = "keyword_research.csv"):
    # Dedup
    unique = list(set(all_queries))
    
    # Intent sınıflandır
    classified = [(q, classify_intent(q)) for q in unique]
    
    # Topic clustering
    clusters = cluster_by_topic(unique)
    
    with open(filename, "w", newline="", encoding="utf-8") as f:
        writer = csv.writer(f)
        writer.writerow(["query", "intent", "cluster_topic", "word_count"])
        for q, intent in classified:
            topic = " ".join(q.split()[:2])
            wc = len(q.split())
            writer.writerow([q, intent, topic, wc])
    
    print(f"{len(unique)} sorgu {filename} dosyasına kaydedildi")
    
    # Intent dağılımı
    intent_counts = defaultdict(int)
    for _, intent in classified:
        intent_counts[intent] += 1
    print("\nIntent dağılımı:")
    for intent, count in sorted(intent_counts.items(), key=lambda x: -x[1]):
        print(f"  {intent}: {count} ({100*count/len(unique):.1f}%)")

# Örnek kullanım
if __name__ == "__main__":
    all_queries = set()
    # Autocomplete, PAA ve Related results'ları birleştir
    # all_queries.update(autocomplete_results)
    # all_queries.update(paa_results)  
    # all_queries.update(related_results)
    # export_to_csv(all_queries)

Bu çıktıyı bir web scraping pipeline'ına bağlayarak haftalık otomatik keyword raporları üretebilirsiniz. ProxyHat fiyatlandırması sayfasından uygun proxy paketini seçebilirsiniz.

Yaygın Hatalar ve Edge Case'ler

  • Locale mismatch: hl ve gl parametreleri proxy lokasyonuyla uyuşmazsa Google karışık öneriler döndürür. Almanya proxy'si kullanıyorsanız hl=de ve gl=de kullanın.
  • Sticky session kaybı: Autocomplete genişletmede her istekte yeni IP kullanmak, Google'ın anlık rate limit'lerini tetikler. session-abc123 bayrağı ile aynı IP'de kalın.
  • PAA selector değişimi: Google sık sık HTML yapısını değiştirir. CSS selector'ları her hafta test edin; kırılma riskini azaltmak için data-attribute tabanlı selector'ları tercih edin.
  • CAPTTCHA tetikleme: Saniyede 10+ istek göndermek CAPTCHA'ya yol açar. Semaphore ile concurrency'yi 5'te tutun ve 500ms gecikme ekleyin.
  • Encoding sorunları: Almanca, Türkçe ve diğer UTF-8 dillerde q parametresini urllib.parse.quote() ile encode edin.

Etik ve Yasal Konular

Bu veriler herkese açık öneri verileridir; ancak Google'ın Hizmet Şartları, otomatik erişimi kısıtlar. Ölçekli üretim kullanımda resmi API'leri tercih edin. Düşük hacimli araştırma için nazik throttle (saniyede <5 istek) ve robots.txt kontrolü yapın. GDPR kapsamında kişisel veri içermeyen sorgu önerileri genellikle anonimdir, ancak kullanıcı gizliliğini her zaman ön planda tutun.

Key Takeaways

  • Üç kaynak, üç intent: Autocomplete = informational, PAA = comparison/deep-dive, Related Searches = transactional.
  • a-z genişletme: Tek seed kelimeden 300+ öneri üretmek için harf bazında genişletme ve modifier prefix'leri kullanın.
  • Residential proxy zorunlu: Locale bias ve rate limit'ler için gate.proxyhat.com:8080 üzerinden ülke/şehir geo-targeting kullanın.
  • Recursive PAA: Playwright ile akordeon tıklaması yaparak iç içe soruları çıkarın; tek sorgudan 20+ soru mümkün.
  • Etik throttle: Concurrency 5, delay 500ms; ölçekli iş için resmi API'leri tercih edin.

SSS

Sık sorulan sorular

Google People Also Ask ve Autocomplete kazıma nedir?

Google People Also Ask (PAA) ve Autocomplete kazıma, arama motorunun sunduğu öneri sorularını ve otomatik tamamlama verilerini programatik olarak toplama işlemidir. Autocomplete endpoint'i (suggestqueries.google.com) JSON döndürürken, PAA soruları HTML içinde akordeon yapısında bulunur. Bu veriler gerçek kullanıcı sorgularını yansıttığı için anahtar kelime araştırmasında değerlidir. Python ile httpx ve Playwright kullanılarak residential proxy üzerinden çekilebilir.

PAA ve Autocomplete kazıma proxy kullanıcıları için neden önemlidir?

Google'ın öneri sistemleri IP bazlı hız sınırları uygular ve coğrafi konuma göre farklı öneriler döndürür. Datacenter IP'leri hızla bloke edilirken residential proxy'ler %90+ başarı oranı sağlar. Ayrıca locale bias nedeniyle doğru lokalize veri için ülke/şehir seviyesinde geo-targeting gereklidir. ProxyHat'ın gate.proxyhat.com:8080 gateway'i üzerinden user-country-DE-city-berlin formatıyla lokasyon belirlenebilir.

PAA ve Autocomplete kazıma için hangi proxy tipi en iyisidir?

Residential proxy'ler bu iş için en iyi seçimdir. Datacenter IP'leri Google tarafından hızla işaretlenir ve CAPTCHA tetikler. Residential proxy'ler gerçek ISP IP'leri olduğu için tespit edilmesi zordur. Mobil proxy'ler de çalışır ancak maliyetleri daha yüksektir. ProxyHat residential proxy'leri ülke ve şehir seviyesinde geo-targeting destekler; bu da farklı bölgeler için lokalize öneri verisi toplamak için kritiktir.

PAA ve Autocomplete kazıma sırasında blokları nasıl önlersiniz?

Blokları önlemek için dört temel strateji kullanın: (1) Concurrency'yi 5 ile sınırlayın ve her istek arasında 500ms bekleme yapın. (2) Sticky session kullanarak aynı IP'de kalın ve rate limit tetiklemeyin. (3) Residential proxy ile gerçek kullanıcı davranışını taklit edin. (4) Doğru locale parametreleri (hl, gl) kullanın ki proxy lokasyonuyla uyuşsun. Ayrıca exponential backoff ile 429 yanıtlarını yönetin ve user-agent header'larını gerçekçi tutun.

Autocomplete verilerinden uzun kuyruklu anahtar kelimeler nasıl üretilir?

Seed kelimeyi a-z harfleri ile genişleterek her harf için ayrı autocomplete isteği gönderin. Ayrıca 'nedir', 'nasıl', 'fiyat' gibi modifier prefix'leri ekleyin. Tek seed kelimeden 300-500 öneri üretilebilir. PAA sorularını recursive olarak genişleterek iç içe sorular çıkarın; her tıklamada 3-4 yeni soru yüklenir. Bu yöntemle bir anahtar kelimeden 50+ soru ve yüzlerce varyasyon elde edilebilir.

Başlamaya hazır mısınız?

148'den fazla ülkede residential, ISP ve mobil proxy'ler. Ücretsiz hesap oluşturun.

Ücretsiz hesap oluştur
← Bloga Dön