← Bloga geri dön

Parser için Retry Mantığı: Tekrar Eden İstekler Trafiğin %40'ını Nasıl Yiyor ve Bunu Nasıl Düzeltirsiniz

Tekrar eden istekler, proxy trafiğinin %40'ına kadarını tüketebilir. Gerçek kayıpları nasıl hesaplayacağınızı ve bunları doğru backoff, devre kesici ve akıllı proxy rotasyonu ile nasıl azaltacağınızı gösteriyoruz.

📅27 Eylül 2026

Eğer proxy faturası, toplanan veri miktarından daha hızlı artıyorsa, sorun neredeyse her zaman yeniden deneme mantığındadır. Parser, başarısız istekleri birkaç kez sessizce tekrar eder, zaman aşımı ve captcha için trafik harcar, ve geliştirici bu harcamaları günlüklerde bile göremez. Gerçek kayıpları nasıl hesaplayacağımızı ve bunları veri kalitesinden ödün vermeden nasıl azaltacağımızı inceleyelim.

Neden yeniden deneme mantığı trafik tüketiyor

Çoğu parser, naif bir yeniden deneme mantığı ile yazılmıştır: eğer istek başarısız olduysa — tekrar et, ve bu 3-5 kez devam eder. Sorun şu ki, her tekrar isteği sadece yeni bir HTTP isteği değil, aynı zamanda tam bir döngüdür: TCP el sıkışması, TLS müzakeresi, sayfanın tamamının yüklenmesi (sadece bir veri bloğu gerekse bile), ve bazen de resimlerin veya JS dosyalarının yeniden yüklenmesi, eğer parser basit bir HTTP istemcisi yerine headless tarayıcı kullanıyorsa.

Yeniden denemeler, konut proxy'leri ile çalışırken özellikle pahalıdır, burada trafik hacme göre ücretlendirilir, istek sayısına göre değil. Bir ürün sayfasına yapılan başarısız bir istek Wildberries'de resimler ve scriptler ile birlikte 300-500 KB'a mal olabilir. Eğer parser zaman aşımında 3 tekrar yapıyorsa, aynı başarısız istek için dört kez üst üste ödeme yapıyorsunuz — ve dördüncü denemenin başarılı olacağına dair bir garanti yok.

İkinci neden — düzeltilemeyen hatalar için yeniden deneme. Eğer site, bot tespitinden dolayı 403 dönerse, aynı parmak izi ve aynı oturum çerezi ile yapılan bir yeniden istek neredeyse kesinlikle aynı yanıtı alacaktır. Parser, IP adresi veya tarayıcı parmak izi değişmeden, matematiksel olarak başarıyla sonuçlanamayacak denemelere trafik harcar.

Gerçekten ne kadar trafik tekrarlar için harcanıyor

Sorunun boyutunu anlamak için basit bir örnek alalım. Parser, bir pazaryerinden ürün kartlarını topluyor, yanıtın ortalama boyutu — 250 KB (HTML + JSON API + kısmen statik). Engellemeler olmadan stabil çalıştığında başarısız isteklerin oranı %5-8 seviyesinde kalır. Ancak, ucuz veri merkezi proxy'leri ile agresif bir şekilde tarama yapıldığında bu oran %25-35'e kadar çıkabilir, çünkü hedef sağlayıcı hızlı bir şekilde kalıbı tanır ve captcha veya IP bazlı geçici yasaklar döndürmeye başlar.

Sayılarla hesaplayalım. Diyelim ki 100.000 ürün kartı toplamak gerekiyor:

Başarısız istek oranı 1 istekte tekrar sayısı (ortalama) Toplam trafik Aşım
%5 0.15 28.75 GB +%15
%15 0.45 36.25 GB +%45
%30 0.90 47.5 GB +%90

Görüldüğü gibi, %30 başarısızlık oranı ve "3 kez tekrar et" stratejisi ile gerçek trafik, teorik minimum olan 25 GB'a göre neredeyse iki katına çıkıyor. Bu fazladan 20+ GB, proxy için doğrudan bütçe kayıplarıdır ve tekrar mantığını gözden geçirerek azaltılabilir.

Parserların yeniden deneme mantığındaki yaygın hatalar

Yeniden deneme mantığını düzeltmeden önce, %90'ında karşılaşılan tipik antipattern'leri tanımak önemlidir:

  • Hata koduna bakılmaksızın yeniden deneme. 403, 429, 500, zaman aşımı, bağlantı kopması gibi her olağanüstü durumda tekrar başlatılır — oysa bunlar için işleme stratejisi farklı olmalıdır.
  • Tekrarlar arasında sabit gecikme. Örneğin, denemeler arasında 2 saniye beklemek, bu ilk deneme mi yoksa beşinci mi olduğuna bakılmaksızın — bu ya site için çok agresif ya da büyük hacimler için çok yavaş.
  • Aynı IP ve aynı oturum ile tekrar. Eğer site, parmak izi nedeniyle isteği engellediyse, aynı parametrelerle yapılan bir tekrar sonucu değiştirmez, ancak trafik harcar.
  • Deneme sayısında üst sınır yok. Bazı parserlar "ölü" URL'lerde takılır ve pes etmeden önce onlarca tekrar yapar.
  • Geçici ve kalıcı hatalar arasında ayrım yok. 404 (sayfa mevcut değil) ve 503 (sunucu geçici olarak kullanılamıyor) farklı mantık gerektirir — ancak genellikle aynı şekilde işlenir.

Python ile Üstel Backoff

Basit ama etkili bir çözüm — jitter (rastgele dağılım) ile üstel gecikme, gereksiz tekrarların sayısını azaltır ve yükü zamana yayar. Denemeler arasında sabit bir bekleme süresi yerine, gecikme üstel olarak artar, bu da siteye engelleme sonrası "soğuma" süresi tanır ve parser'a, neredeyse kesinlikle başarısız olacak isteklere trafik harcamamasını sağlar.

import time
import random
import requests

def fetch_with_backoff(url, proxies, max_retries=4, base_delay=1.0):
    retryable_codes = {429, 500, 502, 503, 504}
    non_retryable_codes = {404, 410}

    for attempt in range(max_retries + 1):
        try:
            response = requests.get(url, proxies=proxies, timeout=10)

            if response.status_code == 200:
                return response

            if response.status_code in non_retryable_codes:
                # tekrar etmenin anlamı yok — sayfa fiziksel olarak mevcut değil
                return None

            if response.status_code not in retryable_codes:
                return None

        except (requests.exceptions.Timeout,
                requests.exceptions.ConnectionError):
            pass  # geçici ağ hatası — tekrar edilebilir

        if attempt == max_retries:
            return None

        # jitter ile üstel gecikme
        delay = base_delay * (2 ** attempt) + random.uniform(0, 1)
        time.sleep(delay)

    return None

Bu kodun temel fikri, hataları üç kategoriye ayırmaktır: düzeltilemeyenler (404, 410), gecikme ile tekrar edilebilenler (429, 500-504, zaman aşımında) ve diğer her şey, ek denemelere harcama yapılmadan başarısız sayılır. Bu tür bir ayrım, naif "her şeyi tekrar et" yaklaşımına göre gereksiz trafiği %20-30 azaltır.

Tavsiye: Retry-After başlığını işleme ekleyin — birçok site, yeniden denemeden önce kaç saniye beklemeniz gerektiğini kendiliğinden belirtir. Bu başlığın göz ardı edilmesi, gereksiz yasakların ve trafiğin yaygın bir nedenidir.

Devre Kesici: Ne zaman durmalıyız

Üstel backoff, bir isteğin düzeyinde yardımcı olur, ancak tüm alanın veya belirli bir proxy düğümünün yüzlerce URL için geçici olarak kullanılamadığı durumları korumaz. Burada devre kesici kalıbına ihtiyaç vardır — "otomatik anahtar", son dönemdeki hata oranını izler ve belirli bir eşiği aşarsa denemeleri geçici olarak durdurur, kapalı bir kapıya vurmaya devam etmek yerine.

class CircuitBreaker:
    def __init__(self, failure_threshold=0.5, window_size=50, cooldown=60):
        self.failure_threshold = failure_threshold
        self.window_size = window_size
        self.cooldown = cooldown
        self.results = []
        self.open_until = 0

    def is_open(self):
        return time.time() < self.open_until

    def record(self, success: bool):
        self.results.append(success)
        if len(self.results) > self.window_size:
            self.results.pop(0)

        if len(self.results) == self.window_size:
            failure_rate = 1 - sum(self.results) / self.window_size
            if failure_rate > self.failure_threshold:
                self.open_until = time.time() + self.cooldown
                self.results.clear()

Mantık basit: son 50 isteğin yarısından fazlası başarısız olursa, parser bu alan veya proxy için denemeleri 60 saniye boyunca durdurur. Bu süre zarfında IP'yi değiştirmek, istek hızını azaltmak veya başka bir proxy havuzuna geçmek mümkündür. Bu, özellikle hedef sitelerle çalışırken önemlidir; bu siteler, istek sıklığı aşıldığında IP aralığını geçici olarak yasaklar — kapalı bir kapıya vurmaya devam etmek, trafiği boşuna harcamak anlamına gelir.

Yeniden denemelerde akıllı proxy rotasyonu

Gereksiz yeniden denemelere karşı en etkili önlemlerden biri, daha önce reddedilen aynı IP ile isteği tekrar etmemektir. Mantık basit: hata IP engeli ile ilgiliyse (403, 429, captcha yönlendirmesi), yeniden deneme öncesinde proxy değiştirmek başarı şansını önemli ölçüde artırır ve deneme sayısını azaltır.

Wildberries, Ozon veya Avito gibi pazaryerlerini tararken, normal istekler veri merkezi proxy'leri üzerinden yapılır — bunlar daha hızlı ve daha ucuzdur, ve engelleme tespit sistemi birkaç kez tetiklendiğinde, parser konut proxy'lerine geçer, bu proxy'ler anti-bot sistemleri tarafından daha az filtrelenir. Bu hibrit yaklaşım, genel trafik tüketimini azaltır, çünkü pahalı konut IP'leri yalnızca gerçekten ihtiyaç duyulduğunda kullanılır, tüm istekler için değil.

Hata türü Yeniden deneme stratejisi IP değişikliği gerekli mi?
Bağlantı zaman aşımı Backoff, 1-2 tekrar Hayır
403 / captcha Anında rotasyon Evet, zorunlu
429 (oran limiti) Retry-After'a göre backoff İhtiyaç duyuluyor
500-503 Backoff, 2-3 tekrar Hayır
404 / 410 Tekrar yok —

Mobil trafik taklit eden parserlar için (örneğin, pazaryerlerinin veya sosyal medya uygulamalarının mobil sürümlerinden veri toplama) mobil proxy'ler kullanmak mantıklıdır — çünkü bu proxy'ler, iletişim operatörlerinin aynı IP'leri binlerce gerçek kullanıcıya aynı anda vermesi nedeniyle koruma sistemlerinde daha az şüphe uyandırır ve noktasal engelleme, hedef site için mantıklı hale gelmez.

Yeniden deneme metriklerinin izlenmesi

Metrikler olmadan, yeniden deneme mantığının optimizasyonu tahmine dönüşür. Her istekte kaydedilmesi gereken minimum gösterge seti:

  • Yeniden deneme oranı — en az bir yeniden deneme gerektiren isteklerin oranı.
  • Yeniden denemeden sonra başarı — hangi yüzdelik dilimin sonunda başarı ile sonuçlandı (bu gösterge düşükse, yeniden denemeler sadece trafiği yakar).
  • Başarılı sonuç için trafik — iletilen toplam veri hacmi, başarıyla toplanan kayıt sayısına bölünür. Bu, etkinliğin ana metriğidir.
  • Hataların kodlara göre dağılımı — trafiğin nerede sızdığını anlamaya yardımcı olur: zaman aşımı, 403, 429 veya başka bir şey.
  • Belirli proxy düğümleri için yeniden deneme oranı — eğer bir IP %80 yeniden deneme oranı veriyorsa, diğerleri %10 ise, sorun yereldir ve belirli bir düğümün değiştirilmesiyle çözülür, tüm mantıkla değil.

Google Sheets'te basit bir tablo veya bu beş metrikle güncellenen bir CSV kaydı, anormallikleri görmek ve stratejiyi zamanında düzeltmek için yeterli veriyi sağlar — örneğin, belirli bir site bölümüne istek sıklığını azaltmak veya proxy havuzundaki konut IP'lerinin oranını artırmak.

Yeniden deneme için trafik optimizasyonu kontrol listesi

  1. Hata kodlarını yeniden denemeye uygun ve uygun olmayanlar olarak ayırın — 404/410'ları tekrar etmeyin.
  2. Sabir gecikme yerine jitter ile üstel backoff uygulayın.
  3. Site bunu gönderiyorsa Retry-After başlığına saygı gösterin.
  4. 403 ve bot tespitinden şüphelenildiğinde yeniden deneme öncesinde IP değiştirin.
  5. Deneme sayısı için katı bir sınır belirleyin (genellikle 3-4 yeterlidir).
  6. Yüksek başarısızlık oranına sahip alanlar ve proxy düğümleri için devre kesici uygulayın.
  7. Yeniden deneme oranını ve başarılı sonuç için trafiği kaydedin — metrikler olmadan optimizasyon mümkün değildir.
  8. Proxy havuzunu ayırın: stabil alanlar için ucuz veri merkezleri, sorunlu alanlar için konut veya mobil IP'ler.

Sonuç

Yeniden deneme mantığı, parser'ın küçük bir detayı değil, veri toplama maliyetini etkileyen ana faktörlerden biridir. Naif "her şeyi tekrar et" stratejisi, teorik minimuma göre gerçek trafiği %40-90 artırabilir, bu arada çoğu yeniden deneme ilk deneme ile aynı başarısızlıkla sonuçlanır. Hataları türlerine göre ayırmak, üstel backoff, devre kesici ve akıllı IP rotasyonu, bu kayıpları önemli ölçüde azaltmayı sağlar, veri toplama kapsamını düşürmeden.

Eğer parser'ınız, botları agresif bir şekilde tespit eden sitelerle çalışıyorsa — pazaryerleri, sosyal medya, reklam platformları — göreve bağlı olarak birkaç proxy türünü birleştirmek önemlidir. Temel işlemler için veri merkezi proxy'leri uygundur, ancak engellemelere karşı maksimum dayanıklılık gerektiğinde, konut proxy'leri ile gerçek kullanıcıların IP adresleri kullanılır. Bu hibrit yaklaşım, etkili bir yeniden deneme mantığı ile birlikte aynı veri toplama hacminde trafik tüketimini önemli ölçüde azaltır.