[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-post-tr-cografi-hedefli-serp-kazima-rehberi":3},{"success":4,"payload":5,"related":62,"errors":129},true,{"id":6,"slug":7,"title":8,"excerpt":9,"body_html":10,"meta_title":11,"meta_description":12,"canonical_url":13,"canonical_override":14,"og_title":11,"og_description":12,"og_image_url":15,"faq_json":16,"key_takeaways":14,"allow_index":29,"noindex_google_only":29,"allow_follow":4,"published_at":30,"updated_at":30,"content_updated_at":31,"featured_image_url":32,"featured_image_alt":33,"card_image_url":34,"reading_time_minutes":35,"author":36,"categories":40,"tags":47,"alternates":48,"locale_paths":50,"views":61},198,"cografi-hedefli-serp-kazima-rehberi","Coğrafi Hedefli SERP Kazıma En İyi Uygulamaları: Geliştirici Rehberi","Google uule, gl, hl parametreleri ile şehir seviyesinde SERP verisi toplama. Residential proxy rotation, sticky session, retry stratejileri ve üretim ortamına hazır Python örnekleri.","\u003Cp>Aynı Google sorgusu İstanbul'da, Berlin'de ve New York'ta tamamen farklı sonuçlar döndürür. Coğrafi hedefli SERP kazıma en iyi uygulamaları konusunda çalışan her SEO mühendisinin çözmesi gereken ilk problem budur. Bu rehberde, uule parametresinin yapımından sticky session'lara kadar tüm teknik katmanı adım adım ele alacağız.\u003C\u002Fp>\n\u003Cp>Eğer rank-tracking pipeline'ınız ülke düzeyinde (gl=US) kalıyorsa, yerel SEO verileriniz eksik kalır. Google sonuçları şehir ve hatta ilçe seviyesinde farklılaşır. Bu yazıda, şehir bazlı lokal SERP kazıma için gereken tüm parametreleri, IP coğrafyası eşleştirme stratejilerini ve üretim ortamına hazır Python kod örneklerini bulacaksınız.\u003C\u002Fp>\n\n\u003Ch2>Coğrafi Hedefli SERP Kazıma En İyi Uygulamaları: Neden Lokasyon Önemli?\u003C\u002Fh2>\n\n\u003Cp>Google, kullanıcının IP adresi, önceki aramalar, dil ayarları ve Google hesabı verilerini birleştirerek kişiselleştirilmiş sonuçlar üretir. Bir kullanıcı \"kahve\" aradığında, Google fiziksel konumuna en yakın kafeleri sıralar. Aynı sorgu farklı şehirlerde farklı işletmeleri gösterir. \u003Ca href=\"https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\" rel=\"noopener noreferrer\">Google Search Central belgeleri\u003C\u002Fa>, lokal arama sonuçlarının kullanıcının konumuna göre optimize edildiğini doğrular.\u003C\u002Fp>\n\n\u003Cp>Ülke düzeyinde hedefleme (gl=US) çoğu durumda yetersizdir. \"dentist\" sorgusu New York'ta Chicago'dan tamamen farklı diş hekimlerini listeler. ABD coğrafi hedefli SERP kazıma en iyi uygulamaları, şehir ve hatta ilçe seviyesinde hassasiyet gerektirir. Bu nedenle sadece gl parametresiyle kalmayıp uule parametresi ile tam şehir konumu sabitlemeniz gerekir.\u003C\u002Fp>\n\n\u003Ch2>Temel Lokalizasyon Parametreleri: gl, hl, google_domain, lr ve uule\u003C\u002Fh2>\n\n\u003Cp>Google SERP'ini lokasyona göre özelleştirmek için kullanılan temel parametreler şunlardır:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>\u003Cstrong>gl\u003C\u002Fstrong>: Ülke kodu (örn. \u003Ccode>us\u003C\u002Fcode>, \u003Ccode>de\u003C\u002Fcode>, \u003Ccode>tr\u003C\u002Fcode>). Sonuçların hangi ülke için optimize edileceğini belirler.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>hl\u003C\u002Fstrong>: Arayüz dili (örn. \u003Ccode>en\u003C\u002Fcode>, \u003Ccode>de\u003C\u002Fcode>, \u003Ccode>tr\u003C\u002Fcode>). Google arama sayfasının dilini ayarlar.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>google_domain\u003C\u002Fstrong>: Hangi Google alan adının kullanılacağı (örn. \u003Ccode>google.com\u003C\u002Fcode>, \u003Ccode>google.de\u003C\u002Fcode>, \u003Ccode>google.com.tr\u003C\u002Fcode>).\u003C\u002Fli>\n\u003Cli>\u003Cstrong>lr\u003C\u002Fstrong>: Dil kısıtlaması (örn. \u003Ccode>lang_en\u003C\u002Fcode>, \u003Ccode>lang_tr\u003C\u002Fcode>). Sonuçların belirli bir dilde olmasını sağlar.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>uule\u003C\u002Fstrong>: Canonical place name tabanlı şehir\u002Flokalasyon sabitleme. En güçlü lokalizasyon parametresidir.\u003C\u002Fli>\n\u003Cli>pws=0: Kişiselleştirmeyi devre dışı bırakır. Tutarlı, tekrarlanabilir sonuçlar için her istekte eklenmelidir.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>SERP gl hl google_domain parametreleri birlikte kullanıldığında ülke ve dil seviyesinde kontrol sağlar. Ancak şehir seviyesinde hassasiyet için uule parametresi şarttır.\u003C\u002Fp>\n\n\u003Ch3>Google uule Parametresi: Şehir Seviyesinde Hassasiyet\u003C\u002Fh3>\n\n\u003Cp>uule parametresi, Google'ın kullanıcının tam konumunu simüle etmesini sağlar. Yapısı üç bölümden oluşur:\u003C\u002Fp>\n\n\u003Col>\n\u003Cli>Sabit önek: \u003Ccode>w+CAEQ\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>Uzunluk anahtarı: Base64 stringinin uzunluğunu tek karakterle kodlar (8→a, 9→b, ..., 33→z, 34→0, ..., 43→9, 44→+, 45→\u002F)\u003C\u002Fli>\n\u003Cli>Base64 kodlu canonical place name: Örn. \u003Ccode>New York,New York,United States\u003C\u002Fcode>\u003C\u002Fli>\n\u003C\u002Fol>\n\n\u003Cp>Örnek: \u003Ccode>New York,New York,United States\u003C\u002Fcode> → base64 → 44 karakter → anahtar \u003Ccode>+\u003C\u002Fcode> → uule değeri: \u003Ccode>w+CAEQ+TmV3IFlvcmssTmV3IFlvcmssVW5pdGVkIFN0YXRlcw==\u003C\u002Fcode>\u003C\u002Fp>\n\n\u003Cp>\u003Ca href=\"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FGoogle_Search\" rel=\"noopener noreferrer\">Wikipedia'nın Google Search makalesi\u003C\u002Fa>, arama motorunun konum bazlı sonuç sunma mekanizmasını detaylandırır. uule parametresi, bu mekanizmayı programatik olarak kontrol etmenin en doğrudan yoludur.\u003C\u002Fp>\n\n\u003Ch2>IP Coğrafyası ve Parametre Uyumu\u003C\u002Fh2>\n\n\u003Cp>Google, URL parametreleri ile istek yapan IP'nin coğrafi konumunu çapraz kontrol eder. Eğer gl=us ve uule=New York parametreleriyle birlikte Almanya merkezli bir datacenter IP'si kullanırsanız, Google tutarsızlık tespit edebilir ve CAPTCHA veya 429 yanıtı döndürebilir.\u003C\u002Fp>\n\n\u003Cp>Bu nedenle istekleri hedef pazarla eşleşen residential proxy üzerinden yönlendirmeniz gerekir. ProxyHat'ın \u003Ccode>gate.proxyhat.com:8080\u003C\u002Fcode> gateway'i, kullanıcı adında ülke ve şehir parametreleriyle coğrafi hedefleme sağlar:\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>curl -x &quot;http:\u002F\u002Fuser-country-US-region-new_york-city-new_york_city:pass@gate.proxyhat.com:8080&quot; \\\n  &quot;https:\u002F\u002Fwww.google.com\u002Fsearch?q=coffee+shop&amp;gl=us&amp;hl=en&amp;uule=w+CAEQ+TmV3IFlvcmssTmV3IFlvcmssVW5pdGVkIFN0YXRlcw==&amp;pws=0&amp;num=100&quot;\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>Bu örnekte IP, ABD\u002FNew York residential havuzundan seçilir ve uule parametresiyle aynı şehri hedefler. Parametreler ve IP coğrafyası uyumlu olduğu için Google tutarlı lokal sonuçlar döndürür.\u003C\u002Fp>\n\n\u003Ch2>Python ile Uygulamalı Örnekler\u003C\u002Fh2>\n\n\u003Ch3>Örnek 1: uule Üretimi ve requests ile Raw Proxy Kullanımı\u003C\u002Fh3>\n\n\u003Cpre>\u003Ccode>import base64\nimport requests\nimport logging\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\n\ndef make_uule(place_name: str) -&gt; str:\n    &quot;&quot;&quot;Google uule parametresini canonical place name&apos;den üretir.&quot;&quot;&quot;\n    b64 = base64.b64encode(place_name.encode(&quot;utf-8&quot;)).decode(&quot;utf-8&quot;)\n    length = len(b64)\n    if 8 &lt;= length &lt;= 33:\n        key = chr(ord(&quot;a&quot;) + length - 8)\n    elif 34 &lt;= length &lt;= 43:\n        key = chr(ord(&quot;0&quot;) + length - 34)\n    elif length == 44:\n        key = &quot;+&quot;\n    elif length == 45:\n        key = &quot;\u002F&quot;\n    else:\n        raise ValueError(f&quot;Unexpected base64 length: {length}&quot;)\n    return f&quot;w+CAEQ{key}{b64}&quot;\n\n# New York için uule değeri\nuule = make_uule(&quot;New York,New York,United States&quot;)\n# Sonuç: w+CAEQ+TmV3IFlvcmssTmV3IFlvcmssVW5pdGVkIFN0YXRlcw==\n\nparams = {\n    &quot;q&quot;: &quot;coffee shop&quot;,\n    &quot;gl&quot;: &quot;us&quot;,\n    &quot;hl&quot;: &quot;en&quot;,\n    &quot;uule&quot;: uule,\n    &quot;pws&quot;: &quot;0&quot;,\n    &quot;num&quot;: &quot;100&quot;,\n}\n\n# Raw proxy URL yapımı\nproxy = &quot;http:\u002F\u002Fuser-country-US-region-new_york-city-new_york_city:pass@gate.proxyhat.com:8080&quot;\nproxies = {&quot;http&quot;: proxy, &quot;https&quot;: proxy}\n\nresp = requests.get(\n    &quot;https:\u002F\u002Fwww.google.com\u002Fsearch&quot;,\n    params=params,\n    proxies=proxies,\n    timeout=30,\n)\nlogger.info(f&quot;Status: {resp.status_code}, Length: {len(resp.text)}&quot;)\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch3>Örnek 2: curl_cffi ile Chrome Taklidi\u003C\u002Fh3>\n\n\u003Cp>Google, TLS parmak iziyle bot tespiti yapar. Standart \u003Ccode>requests\u003C\u002Fcode> kütüphanesinin TLS imzası kolayca tanınır. \u003Ccode>curl_cffi\u003C\u002Fcode> ile Chrome TLS parmak izini taklit edebilirsiniz:\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>from curl_cffi import requests as cffi_requests\n\ndef scrape_serp_cffi(query: str, country: str, region: str, city: str, lang: str = &quot;en&quot;):\n    uule = make_uule(f&quot;{city.title()},{region.title()},United States&quot;)\n    params = {\n        &quot;q&quot;: query,\n        &quot;gl&quot;: country,\n        &quot;hl&quot;: lang,\n        &quot;uule&quot;: uule,\n        &quot;pws&quot;: &quot;0&quot;,\n        &quot;num&quot;: &quot;100&quot;,\n    }\n    proxy = (\n        f&quot;http:\u002F\u002Fuser-country-{country.upper()}-region-{region}-city-{city.lower()}&quot;\n        f&quot;:pass@gate.proxyhat.com:8080&quot;\n    )\n\n    resp = cffi_requests.get(\n        &quot;https:\u002F\u002Fwww.google.com\u002Fsearch&quot;,\n        params=params,\n        proxies={&quot;https&quot;: proxy},\n        impersonate=&quot;chrome&quot;,\n        timeout=30,\n    )\n    return resp\n\nresp = scrape_serp_cffi(&quot;best pizza&quot;, &quot;us&quot;, &quot;illinois&quot;, &quot;chicago&quot;)\nprint(f&quot;Status: {resp.status_code}, Bytes: {len(resp.text)}&quot;)\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch3>Örnek 3: selectolax ile Organik Sonuçları ve Local Pack'i Parse Etme\u003C\u002Fh3>\n\n\u003Cpre>\u003Ccode>from selectolax.parser import HTMLParser\n\ndef parse_serp(html: str) -&gt; dict:\n    tree = HTMLParser(html)\n    results = {&quot;organic&quot;: [], &quot;local_pack&quot;: []}\n\n    # Organik sonuçlar\n    for div in tree.css(&quot;div.g&quot;):\n        title_el = div.css_first(&quot;h3&quot;)\n        link_el = div.css_first(&quot;a[href]&quot;)\n        if title_el and link_el:\n            results[&quot;organic&quot;].append({\n                &quot;title&quot;: title_el.text(),\n                &quot;url&quot;: link_el.attributes.get(&quot;href&quot;, &quot;&quot;),\n            })\n\n    # Local pack (Google Business sonuçları)\n    for div in tree.css(&quot;div[role=&apos;heading&apos;]&quot;):\n        parent = div.parent\n        if parent:\n            cls = parent.attributes.get(&quot;class&quot;, &quot;&quot;)\n            if &quot;local&quot; in cls.lower() or &quot;business&quot; in cls.lower():\n                results[&quot;local_pack&quot;].append({\n                    &quot;name&quot;: div.text(),\n                })\n\n    return results\n\ndata = parse_serp(resp.text)\nprint(f&quot;Organik sonuç: {len(data[&apos;organic&apos;])}&quot;)\nprint(f&quot;Local pack: {len(data[&apos;local_pack&apos;])}&quot;)\nfor item in data[&quot;organic&quot;][:5]:\n    print(f&quot;  - {item[&apos;title&apos;]}&quot;)\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch3>Örnek 4: Sticky Session ile Çok Sayfalı SERP\u003C\u002Fh3>\n\n\u003Cp>Çok sayfalı SERP kazımada, sayfalar arası tutarlılık için aynı IP'yi kullanmanız gerekir. ProxyHat'ın session parametresi ile sticky session oluşturabilirsiniz:\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>import uuid\n\ndef scrape_multi_page(query: str, country: str, region: str, city: str, max_pages: int = 3):\n    session_id = str(uuid.uuid4())[:8]\n    # Sticky session: aynı IP tüm sayfalarda korunur\n    proxy = (\n        f&quot;http:\u002F\u002Fuser-country-{country.upper()}-region-{region}-city-{city.lower()}&quot;\n        f&quot;-sid-{session_id}:pass@gate.proxyhat.com:8080&quot;\n    )\n    proxies = {&quot;http&quot;: proxy, &quot;https&quot;: proxy}\n\n    all_results = []\n    for page in range(max_pages):\n        params = {\n            &quot;q&quot;: query,\n            &quot;gl&quot;: country,\n            &quot;hl&quot;: &quot;en&quot;,\n            &quot;uule&quot;: make_uule(f&quot;{city.title()},{region.title()},United States&quot;),\n            &quot;pws&quot;: &quot;0&quot;,\n            &quot;start&quot;: str(page * 10),\n        }\n        resp = requests.get(\n            &quot;https:\u002F\u002Fwww.google.com\u002Fsearch&quot;,\n            params=params,\n            proxies=proxies,\n            timeout=30,\n        )\n        if resp.status_code == 200:\n            page_data = parse_serp(resp.text)\n            all_results.extend(page_data[&quot;organic&quot;])\n            logger.info(f&quot;Sayfa {page}: {len(page_data[&apos;organic&apos;])} sonuç&quot;)\n        else:\n            logger.warning(f&quot;Sayfa {page}: HTTP {resp.status_code} - durduruluyor&quot;)\n            break\n    return all_results\n\nresults = scrape_multi_page(&quot;dentist&quot;, &quot;us&quot;, &quot;illinois&quot;, &quot;chicago&quot;, max_pages=3)\nprint(f&quot;Toplam sonuç: {len(results)}&quot;)\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch3>Örnek 5: ProxyHat SDK Wrapper ile Basitleştirilmiş Kullanım\u003C\u002Fh3>\n\n\u003Cpre>\u003Ccode>import uuid\nimport time\nimport logging\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\n\nclass ProxyHatSERP:\n    &quot;&quot;&quot;ProxyHat residential proxy ile geo-targeted SERP kazıma SDK wrapper.&quot;&quot;&quot;\n\n    GATEWAY = &quot;gate.proxyhat.com&quot;\n    HTTP_PORT = 8080\n    SOCKS5_PORT = 1080\n\n    def __init__(self, username: str, password: str):\n        self.username = username\n        self.password = password\n\n    def get_proxy(self, country: str, region: str = None, city: str = None,\n                  session: str = None, socks5: bool = False) -&gt; dict:\n        user = f&quot;{self.username}-country-{country.upper()}&quot;\n        if region and city:\n            user += f&quot;-region-{region}-city-{city.lower()}&quot;\n        elif region:\n            user += f&quot;-region-{region}&quot;\n        if session:\n            user += f&quot;-sid-{session}&quot;\n\n        port = self.SOCKS5_PORT if socks5 else self.HTTP_PORT\n        scheme = &quot;socks5&quot; if socks5 else &quot;http&quot;\n        proxy_url = f&quot;{scheme}:\u002F\u002F{user}:{self.password}@{self.GATEWAY}:{port}&quot;\n        return {&quot;http&quot;: proxy_url, &quot;https&quot;: proxy_url}\n\n    def scrape(self, query: str, country: str, region: str, city: str,\n               lang: str = &quot;en&quot;, pages: int = 1) -&gt; list:\n        session_id = str(uuid.uuid4())[:8] if pages &gt; 1 else None\n        proxies = self.get_proxy(country, region, city, session_id)\n        uule = make_uule(f&quot;{city.title()},{region.title()},United States&quot;)\n\n        all_results = []\n        for page in range(pages):\n            params = {\n                &quot;q&quot;: query, &quot;gl&quot;: country, &quot;hl&quot;: lang,\n                &quot;uule&quot;: uule, &quot;pws&quot;: &quot;0&quot;, &quot;num&quot;: &quot;100&quot;,\n                &quot;start&quot;: str(page * 10),\n            }\n            resp = requests.get(\n                &quot;https:\u002F\u002Fwww.google.com\u002Fsearch&quot;,\n                params=params, proxies=proxies, timeout=30,\n            )\n            if resp.status_code == 200:\n                data = parse_serp(resp.text)\n                all_results.append(data)\n                logger.info(f&quot;Sayfa {page}: {len(data[&apos;organic&apos;])} organik sonuç&quot;)\n            else:\n                logger.warning(f&quot;Sayfa {page}: HTTP {resp.status_code}&quot;)\n        return all_results\n\n# Kullanım - raw proxy yerine temiz SDK arayüzü\nscraper = ProxyHatSERP(&quot;user&quot;, &quot;pass&quot;)\ndata = scraper.scrape(&quot;plumber&quot;, &quot;US&quot;, &quot;illinois&quot;, &quot;chicago&quot;, pages=2)\nfor page_data in data:\n    for item in page_data[&quot;organic&quot;][:3]:\n        print(f&quot;  {item[&apos;title&apos;]}&quot;)\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch3>Örnek 6: CAPTCHA\u002F429 Backoff ve Retry Stratejisi\u003C\u002Fh3>\n\n\u003Cpre>\u003Ccode>import time\n\nclass SERPScraper:\n    &quot;&quot;&quot;Exponential backoff ve circuit breaker ile güvenli SERP kazıma.&quot;&quot;&quot;\n\n    def __init__(self, max_retries: int = 3, base_delay: float = 5.0,\n                 failure_threshold: int = 5):\n        self.max_retries = max_retries\n        self.base_delay = base_delay\n        self.failure_threshold = failure_threshold\n        self.circuit_open = False\n        self.failure_count = 0\n\n    def fetch_with_retry(self, url: str, params: dict, proxy: str) -&gt; str:\n        if self.circuit_open:\n            raise RuntimeError(&quot;Circuit breaker açık - daha sonra tekrar deneyin&quot;)\n\n        for attempt in range(self.max_retries):\n            try:\n                resp = requests.get(\n                    url,\n                    params=params,\n                    proxies={&quot;https&quot;: proxy},\n                    timeout=30,\n                )\n                if resp.status_code == 200:\n                    self.failure_count = 0\n                    return resp.text\n                elif resp.status_code == 429:\n                    delay = self.base_delay * (2 ** attempt)\n                    logger.warning(f&quot;429 alındı, {delay}s bekleniyor (deneme {attempt+1}\u002F{self.max_retries})&quot;)\n                    time.sleep(delay)\n                elif resp.status_code == 503:\n                    logger.warning(f&quot;CAPTCHA\u002F503 - deneme {attempt+1}&quot;)\n                    time.sleep(self.base_delay * (attempt + 1))\n                else:\n                    logger.error(f&quot;HTTP {resp.status_code} - durduruluyor&quot;)\n                    break\n            except requests.RequestException as e:\n                logger.error(f&quot;İstek hatası: {e}&quot;)\n                time.sleep(self.base_delay)\n\n        self.failure_count += 1\n        if self.failure_count &gt;= self.failure_threshold:\n            self.circuit_open = True\n            logger.error(f&quot;Circuit breaker açıldı! {self.failure_threshold} ardışık hata.&quot;)\n        return &quot;&quot;\n\n    def reset_circuit(self):\n        self.circuit_open = False\n        self.failure_count = 0\n        logger.info(&quot;Circuit breaker sıfırlandı.&quot;)\n\n# Ülke bazlı proxy havuzu\nPROXY_POOLS = {\n    &quot;US&quot;: [\n        &quot;http:\u002F\u002Fuser-country-US-region-new_york-city-new_york_city:pass@gate.proxyhat.com:8080&quot;,\n        &quot;http:\u002F\u002Fuser-country-US-region-illinois-city-chicago:pass@gate.proxyhat.com:8080&quot;,\n        &quot;http:\u002F\u002Fuser-country-US-region-california-city-los_angeles:pass@gate.proxyhat.com:8080&quot;,\n    ],\n    &quot;DE&quot;: [\n        &quot;http:\u002F\u002Fuser-country-DE-region-state_of_berlin-city-berlin:pass@gate.proxyhat.com:8080&quot;,\n        &quot;http:\u002F\u002Fuser-country-DE-region-bayern-city-munich:pass@gate.proxyhat.com:8080&quot;,\n    ],\n}\n\nscraper = SERPScraper(max_retries=3, base_delay=5.0)\n\n# ABD\u002FNew York için kazıma\nproxy = PROXY_POOLS[&quot;US&quot;][0]\nuule = make_uule(&quot;New York,New York,United States&quot;)\nhtml = scraper.fetch_with_retry(\n    &quot;https:\u002F\u002Fwww.google.com\u002Fsearch&quot;,\n    {&quot;q&quot;: &quot;restaurant&quot;, &quot;gl&quot;: &quot;us&quot;, &quot;hl&quot;: &quot;en&quot;, &quot;uule&quot;: uule, &quot;pws&quot;: &quot;0&quot;},\n    proxy,\n)\nif html:\n    results = parse_serp(html)\n    print(f&quot;Organik: {len(results[&apos;organic&apos;])}, Local: {len(results[&apos;local_pack&apos;])}&quot;)\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>Yaygın Hatalar ve Edge Case'ler\u003C\u002Fh2>\n\n\u003Cul>\n\u003Cli>Parametre-IP uyumsuzluğu: gl=us parametresiyle Almanya IP'si kullanmak, Google'ın tutarsızlık tespitine yol açar. Her zaman hedef lokasyonla eşleşen residential proxy kullanın.\u003C\u002Fli>\n\u003Cli>pws=0 eksikliği: Kişiselleştirme açıkken aynı sorgu farklı oturumlarda farklı sonuçlar döndürür. Tutarlı veri için her istekte pws=0 ekleyin.\u003C\u002Fli>\n\u003Cli>uule formatı yanlış: Base64 uzunluğu 46'dan büyükse veya 8'den küçükse length key hesaplanamaz. Canonical place name formatını kontrol edin (örn. \"City,State,Country\").\u003C\u002Fli>\n\u003Cli>Rate limiting: Aynı IP'den saniyede 5'den fazla istek göndermek 429 yanıtı tetikler. ProxyHat residential havuzunda IP rotation ile bu sınırı yönetin. 100 eşzamanlı oturum için farklı session ID'leri kullanın.\u003C\u002Fli>\n\u003Cli>Eski CSS selector'lar: Google HTML yapısını sık değiştirir. selectolax selector'larınızı her 2-4 haftada bir test edin.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Ch2>Proxy Tipleri Karşılaştırması\u003C\u002Fh2>\n\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Proxy Tipi\u003C\u002Fth>\u003Cth>Başarı Oranı\u003C\u002Fth>\u003Cth>Latans\u003C\u002Fth>\u003Cth>Fiyat\u002F1GB\u003C\u002Fth>\u003Cth>SERP İçin Uygunluk\u003C\u002Fth>\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Residential\u003C\u002Ftd>\u003Ctd>~95%\u003C\u002Ftd>\u003Ctd>200-800ms\u003C\u002Ftd>\u003Ctd>Orta\u003C\u002Ftd>\u003Ctd>En iyi — gerçek ISP IP'leri\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Datacenter\u003C\u002Ftd>\u003Ctd>~40%\u003C\u002Ftd>\u003Ctd>50-200ms\u003C\u002Ftd>\u003Ctd>Düşük\u003C\u002Ftd>\u003Ctd>Zayıf — Google datacenter IP'leri tespit eder\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Mobile\u003C\u002Ftd>\u003Ctd>~98%\u003C\u002Ftd>\u003Ctd>500-2000ms\u003C\u002Ftd>\u003Ctd>Yüksek\u003C\u002Ftd>\u003Ctd>İyi — yüksek riskli hedefler için\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\n\u003Cp>SERP kazıma için residential proxy'ler en iyi dengeyi sunar. ProxyHat'ın \u003Ca href=\"\u002Ftr\u002Fpricing\">pricing sayfasından\u003C\u002Fa> residential proxy paketlerini inceleyebilir, \u003Ca href=\"\u002Ftr\u002Flocations\">locations sayfasından\u003C\u002Fa> mevcut ülke ve şehir listesini görebilirsiniz. Daha fazla bilgi için \u003Ca href=\"https:\u002F\u002Fdocs.proxyhat.com\u002F\" rel=\"noopener noreferrer\">ProxyHat dokümantasyonunu\u003C\u002Fa> ziyaret edin.\u003C\u002Fp>\n\n\u003Ch2>Hukuki ve Etik Hususlar\u003C\u002Fh2>\n\n\u003Cp>Google'ın Hizmet Şartları otomatik veri toplamaya izin vermez. SERP kazıma yapmadan önce:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Google'ın \u003Ca href=\"https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\" rel=\"noopener noreferrer\">Search Central belgelerini\u003C\u002Fa> ve robots.txt kurallarını inceleyin.\u003C\u002Fli>\n\u003Cli>Hedef sitenin ToS'unu kontrol edin.\u003C\u002Fli>\n\u003Cli>GDPR ve CCPA kapsamında kişisel veri toplamaktan kaçının.\u003C\u002Fli>\n\u003Cli>Rate limiting uygulayın ve hedef sunucuya aşırı yük bindirmeyin.\u003C\u002Fli>\n\u003Cli>Topladığınız verinin kullanım amacını netleştirin — rekabet analizi ve SEO araştırması genellikle kabul edilebilir kullanımlardır.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>Yasal tavsiye için bir avukata danışın. Bu rehber teknik bilgi amaçlıdır ve hukuki tavsiye içermez.\u003C\u002Fp>\n\n\u003Ch2>Önemli Çıkarımlar\u003C\u002Fh2>\n\n\u003Cblockquote>\n\u003Cp>Key Takeaways:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Ülke düzeyinde gl parametresi yetersizdir — şehir hassasiyeti için uule kullanın.\u003C\u002Fli>\n\u003Cli>uule = sabit önek (w+CAEQ) + length key + base64(canonical place name).\u003C\u002Fli>\n\u003Cli>Her istekte pws=0 ekleyerek kişiselleştirmeyi devre dışı bırakın.\u003C\u002Fli>\n\u003Cli>IP coğrafyası ile URL parametreleri her zaman uyumlu olmalıdır — residential proxy kullanın.\u003C\u002Fli>\n\u003Cli>Çok sayfalı SERP için sticky session (session ID) kullanın.\u003C\u002Fli>\n\u003Cli>429 ve 503 yanıtları için exponential backoff + circuit breaker uygulayın.\u003C\u002Fli>\n\u003Cli>Google HTML yapısını sık değiştirir — selector'larınızı düzenli test edin.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fblockquote>\n\n\u003Cp>SERP kazıma pipeline'ınızı kurmaya hazır mısınız? \u003Ca href=\"\u002Ftr\u002Fuse-cases\u002Fserp-tracking\">SERP tracking use case sayfamızdan\u003C\u002Fa> başlayın, \u003Ca href=\"\u002Ftr\u002Fuse-cases\u002Fweb-scraping\">web scraping use case'i\u003C\u002Fa> ile genel kazıma stratejilerinizi genişletin.\u003C\u002Fp>","Coğrafi Hedefli SERP Kazıma En İyi Uygulamaları | ProxyHat","Google uule, gl, hl parametreleri ile şehir seviyesinde SERP kazıma. Residential proxy rotation, sticky session ve retry stratejileri için pratik Python rehberi.","\u002Ftr\u002Fblog\u002Fcografi-hedefli-serp-kazima-rehberi",null,"https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Ftr\u002Fcografi-hedefli-serp-kazima-rehberi-og.webp",[17,20,23,26],{"question":18,"answer":19},"Google uule parametresi nedir ve nasıl kullanılır?","Google uule parametresi, arama sonuçlarının belirli bir şehir veya lokalasyona sabitlenmesini sağlar. Yapısı üç bölümden oluşur: sabit w+CAEQ öneki, base64 string uzunluğunu kodlayan tek karakterlik length key, ve canonical place name'in base64 kodlu hali. Örneğin New York için uule değeri w+CAEQ+TmV3IFlvcmssTmV3IFlvcmssVW5pdGVkIFN0YXRlcw== şeklindedir. Bu parametre gl'den daha hassas lokal sonuçlar sağlar.",{"question":21,"answer":22},"SERP kazıma için hangi proxy tipi en iyisidir?","SERP kazıma için residential proxy'ler en iyi seçenektir. Gerçek ISP IP'leri kullandıkları için Google tarafından datacenter IP'lerine kıyasla çok daha az tespit edilirler. Residential proxy'lerle ~95% başarı oranı elde edilirken, datacenter proxy'lerde bu oran ~40%'a düşer. Mobile proxy'ler ~98% başarı oranı sunsa da daha yüksek latans ve maliyet nedeniyle genellikle yüksek riskli hedefler için reservedir.",{"question":24,"answer":25},"SERP kazımada engellenmeyi nasıl önlersiniz?","Engellenmeyi önlemek için: hedef lokasyonla eşleşen residential proxy kullanın, curl_cffi ile Chrome TLS parmak izini taklit edin, saniyede 5'den az istek gönderin, 429 yanıtlarında exponential backoff uygulayın, sticky session ile IP tutarlılığı sağlayın, ve her istekte pws=0 parametresini ekleyin. Ayrıca circuit breaker pattern ile ardışık hatalarda kazımayı durdurup sonra yeniden deneyin.",{"question":27,"answer":28},"gl, hl ve google_domain parametreleri arasındaki fark nedir?","gl parametresi sonuçların hangi ülke için optimize edileceğini belirler (örn. us, de). hl parametresi Google arayüzünün dilini ayarlar (örn. en, de). google_domain ise isteğin hangi Google alan adına yapılacağını kontrol eder (örn. google.com, google.de). lr parametresi ise sonuçların belirli bir dilde olmasını zorunlu kılar (örn. lang_en). Bu parametreler birlikte kullanıldığında ülke ve dil seviyesinde kontrol sağlar, ancak şehir hassasiyeti için uule gereklidir.",false,"2026-07-31T16:11:16+00:00","2026-10-03T23:52:59+00:00","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Ftr\u002Fcografi-hedefli-serp-kazima-rehberi-master.webp","Geo-Targeted SERP Scraping Best Practices for Local SEO Data","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Ftr\u002Fcografi-hedefli-serp-kazima-rehberi-card.webp",12,{"name":37,"slug":38,"bio":39,"avatar_url":14,"website_url":14,"social_links":14},"ProxyHat Team","proxyhat-team","The ProxyHat editorial team covers proxies, web scraping, and data extraction.",[41],{"id":42,"slug":43,"name":44,"description":14,"meta_title":45,"meta_description":46,"parent_id":14},3,"serp-ve-seo","SERP ve SEO","SERP ve SEO Rehberleri | ProxyHat Blog","Proxy ile arama motoru sıralamalarını takip etme ve SERP verisi toplama rehberleri.",[],{"en":49,"x-default":49},"\u002Fblog\u002Fgeo-targeted-serp-scraping-best-practices",{"zh":51,"ja":52,"pl":53,"es":54,"it":55,"tr":13,"ko":56,"en":49,"ru":57,"de":58,"fr":59,"pt":60},"\u002Fcn\u002Fblog\u002Fserp-dili-dingwei-zhuaqu-zhinan","\u002Fja\u002Fblog\u002Fgeo-targeted-serp-scraping-guide","\u002Fpl\u002Fblog\u002Fgeotargetowane-scrapowanie-serp-najlepsze-praktyki","\u002Fes\u002Fblog\u002Fscraping-serp-geo-segmentado-mejores-practicas","\u002Fit\u002Fblog\u002Fscraping-serp-geo-targetato-best-practices","\u002Fko\u002Fblog\u002Fgeo-targeted-serp-scraping-guide","\u002Fru\u002Fblog\u002Fgeo-targeted-serp-scraping-best-practices","\u002Fde\u002Fblog\u002Fgeo-targeted-serp-scraping-leitfaden","\u002Ffr\u002Fblog\u002Fscraping-serp-geocible-meilleures-pratiques","\u002Fpt\u002Fblog\u002Fpraticas-serp-scraping-geo-targeted",59,[63,80,96,113],{"id":64,"slug":65,"title":66,"excerpt":67,"featured_image_url":68,"featured_image_alt":69,"card_image_url":70,"og_image_url":71,"published_at":72,"updated_at":72,"content_updated_at":73,"reading_time_minutes":74,"is_featured":29,"indexable":4,"views":75,"author":76,"categories":77,"tags":79},155,"proxy-ile-amazon-anahtar-kelime-siralama-takibi","Proxy ile Pazar Yeri Anahtar Kelime Sıralama Takibi: Geliştirici Rehberi (Amazon Örneği)","Amazon SERP'ini kazıyarak anahtar kelime sıralamalarını takip etmek için residential proxy'ler, Python kod örnekleri ve production ipuçlarını içeren kapsamlı geliştirici rehberi.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Ftr\u002Fproxy-ile-amazon-anahtar-kelime-siralama-takibi-master.webp","Amazon Keyword Rank Tracking with Proxies: A Developer's Guide","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Ftr\u002Fproxy-ile-amazon-anahtar-kelime-siralama-takibi-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Ftr\u002Fproxy-ile-amazon-anahtar-kelime-siralama-takibi-og.webp","2026-07-16T16:05:31+00:00","2026-10-04T01:29:51+00:00",13,98,{"name":37,"slug":38,"bio":39,"avatar_url":14,"website_url":14,"social_links":14},[78],{"id":42,"slug":43,"name":44,"description":14,"meta_title":45,"meta_description":46,"parent_id":14},[],{"id":81,"slug":82,"title":83,"excerpt":84,"featured_image_url":85,"featured_image_alt":86,"card_image_url":87,"og_image_url":88,"published_at":89,"updated_at":89,"content_updated_at":90,"reading_time_minutes":35,"is_featured":29,"indexable":29,"views":91,"author":92,"categories":93,"tags":95},153,"google-paa-autocomplete-kazima-rehberi","Google People Also Ask ve Autocomplete Kazıma Rehberi: Python ile Anahtar Kelime Araştırması","Google People Also Ask ve Autocomplete verilerini Python, httpx ve Playwright ile kazıyın. Residential proxy kullanarak IP engellemelerini aşın ve uzun kuyruklu anahtar kelimeleri içerik planlaması için kümeleyin.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Ftr\u002Fgoogle-paa-autocomplete-kazima-rehberi-master.webp","Scrape Google People Also Ask and Autocomplete for Keyword Research (Python Guide)","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Ftr\u002Fgoogle-paa-autocomplete-kazima-rehberi-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Ftr\u002Fgoogle-paa-autocomplete-kazima-rehberi-og.webp","2026-07-14T16:06:25+00:00","2026-10-03T08:29:54+00:00",124,{"name":37,"slug":38,"bio":39,"avatar_url":14,"website_url":14,"social_links":14},[94],{"id":42,"slug":43,"name":44,"description":14,"meta_title":45,"meta_description":46,"parent_id":14},[],{"id":97,"slug":98,"title":99,"excerpt":100,"featured_image_url":101,"featured_image_alt":102,"card_image_url":103,"og_image_url":104,"published_at":105,"updated_at":105,"content_updated_at":106,"reading_time_minutes":107,"is_featured":29,"indexable":29,"views":108,"author":109,"categories":110,"tags":112},154,"google-ai-overviews-marka-takibi","Google AI Overviews'da Marka Takibi: Stratejik Rehber","Google AI Overviews'da marka görünürlüğünüzü ölçmek için stratejik rehber. Citation share KPI'sı, build-vs-buy analizi ve ProxyHat ile headless browser pipeline kurulumu.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Ftr\u002Fgoogle-ai-overviews-marka-takibi-master.webp","How to Track Your Brand in Google AI Overviews: A Strategic Guide for SEO & Data Teams","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Ftr\u002Fgoogle-ai-overviews-marka-takibi-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Ftr\u002Fgoogle-ai-overviews-marka-takibi-og.webp","2026-07-14T10:05:37+00:00","2026-10-03T08:29:51+00:00",10,66,{"name":37,"slug":38,"bio":39,"avatar_url":14,"website_url":14,"social_links":14},[111],{"id":42,"slug":43,"name":44,"description":14,"meta_title":45,"meta_description":46,"parent_id":14},[],{"id":114,"slug":115,"title":116,"excerpt":117,"featured_image_url":118,"featured_image_alt":119,"card_image_url":120,"og_image_url":121,"published_at":122,"updated_at":122,"content_updated_at":123,"reading_time_minutes":35,"is_featured":29,"indexable":29,"views":124,"author":125,"categories":126,"tags":128},152,"python-google-siralama-takipcisi-residential-proxy","Python ile Residential Proxy Kullanarak Google Sıralama Takipçisi Oluşturun","Google'ın num=100 parametresini kaldırması ve TLS parmak izi (JA3\u002FJA4) uygulaması sonrası Python'da üretim düzeyinde bir SERP sıralama takipçisi nasıl kurulur? curl_cffi, ProxyHat residential proxy, SQLite depolama ve tekrar deneme stratejileri ile tam rehber.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Ftr\u002Fpython-google-siralama-takipcisi-residential-proxy-master.webp","Build a Google Rank Tracker in Python with Residential Proxies","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Ftr\u002Fpython-google-siralama-takipcisi-residential-proxy-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Ftr\u002Fpython-google-siralama-takipcisi-residential-proxy-og.webp","2026-07-02T16:04:58+00:00","2026-10-04T02:43:17+00:00",56,{"name":37,"slug":38,"bio":39,"avatar_url":14,"website_url":14,"social_links":14},[127],{"id":42,"slug":43,"name":44,"description":14,"meta_title":45,"meta_description":46,"parent_id":14},[],[]]