Eğer Wildberries veya Ozon parseliniz aniden boş sayfalar, zaman aşımı ve 403 hataları vermeye başladıysa, sorun her zaman platformda değildir. Çoğu zaman proxy havuzundaki bazı IP adresleri zaten "bozulmuş" durumda: yasaklanmış, yavaşlatılmış veya CAPTCHA'ya alınmışlardır. Çalışan bir proxy ile ölü bir proxy'yi ayırt etmek için hangi metriklerin kullanılacağını ve manuel kontrol olmadan ayıklamayı nasıl otomatikleştireceğimizi inceliyoruz.
Neden proxy havuzu zamanla bozulur
Herhangi bir proxy havuzu - güvenilir bir sağlayıcıdan satın alınmış olsa bile - zamanla çalışan adreslerin bir kısmını kaybeder. Sebepler çeşitlidir: Wildberries, Ozon ve Avito'nun anti-fraud sistemleri IP'lerde itibar etiketleri biriktirir, bazı adresler sağlayıcının diğer müşterilerinin toplu talepleri sonrasında kara listeye alınır (eğer proxy paylaşımlıysa), veri merkezi aralıkları alt ağlara göre topluca yasaklanır ve yerel IP'ler bazen sadece gerçek kullanıcı cihazını kapattığı için havuzdan çıkar.
Eğer havuzu temizlemezseniz, "ölü" proxy'lerin oranı doğrusal olmayan bir şekilde artar: önce %5, bir haftalık aktif parselikten sonra - %20-30. Parseliyici, çalışmayan IP'ler üzerinden tekrar denemeler yapmak için kaynak harcamaya başlar, bir sayfanın toplanma süresi artar ve günlüklerde gerçek sorunları maskeleyen hatalar birikir (örneğin, web sayfasının düzeninin değiştirilmesi). Ayıklama sistemi olmadan ya havuzu "yedek" olarak şişirirsiniz ya da düzenli olarak veri toplama başarısızlıkları yaşarsınız.
Görev, hatanın varlığını sadece kaydetmek değil, aynı zamanda onu sınıflandırmaktır: sunucu aşırı yüklenmesi, belirli bir IP'nin yasaklanması, bölgesel engelleme veya parseliyici tarafında bir sorun (geçersiz başlıklar, eski çerezler). Hatanın türüne bağlı olarak, proxy'yi havuzdan sonsuza dek atıp atmayacağınız, "karantinaya" alıp almayacağınız veya sadece isteği tekrarlayıp tekrarlamayacağınız belirlenir.
Ayıklama için ana hata metrikleri
Geçici bir arızayı gerçekten ölü bir proxy'den ayırmak için, her IP için birkaç metrik toplamak gerekir, tek bir HTTP durumu ile yönelmek yerine. İşte her istekte kaydedilmesi gereken temel set:
| Metrik | Ne sinyal veriyor | Eylem |
|---|---|---|
| HTTP 403 / 429 | IP üzerinde yasak veya rate-limit | 30-60 dakika karantina, tekrarında - silme |
| Bağlantı zaman aşımı | Proxy aşırı yüklenmiş veya ölü | Arka arkaya 3 zaman aşımı - havuzdan silme |
| Yanıtta CAPTCHA | IP, anti-bot tarafından şüpheli hale geldi | İstek sıklığını azalt veya IP'yi değiştir |
| Yanıt süresi > 5 sn | Proxy tarafında hızın bozulması | Havuzda önceliği düşür |
| Yanıt boyutu ortalamanın altında | Engelleme sayfası/placeholder verildi | Kabul etmeden önce içeriği ek kontrol et |
| Başarılı istek oranı (success rate) | IP kalitesinin toplam değerlendirmesi | 50 istekte %70'in altında - silme |
Web sitesinin hata kodlarını ağ hatalarıyla karıştırmamak önemlidir. Örneğin, 404 - proxy'nin değil, Wildberries'teki bir ürünün eksik olduğunu gösterir. Ancak aynı IP sürekli olarak 403 alıyorsa, diğer IP'ler 200 alıyorsa, bu belirli bir adresin yasaklandığının açık bir işaretidir.
Proxy skorlama algoritması
İki durumlu "çalışan / çalışmayan" yerine, her IP için 0 ile 100 arasında bir skor hesaplamak daha uygundur; bu skor hatalarla yavaşça düşer ve başarılı isteklerle geri yükselir. Bu, bir rastgele arıza sonrası proxy'yi atmamayı sağlar (pazar yeri sunucusu sadece bir saniye boyunca donmuş olabilir), ancak sistematik olarak çöp döken IP'leri hızlıca kaldırmayı sağlar.
Mantık basit: geçerli içeriğe sahip 200 kodlu başarılı bir istek skora +2 ekler (ama 100'ün üzerine çıkamaz). Zaman aşımı -15. 403/429 kodu -25. Yanıtta CAPTCHA -20. Eğer skor belirli bir eşiğin (örneğin, 30) altına düşerse, proxy sabit bir süre için karantinaya alınır ve eğer karantinadan döndükten sonra skor tekrar 10'un altına düşerse - IP kalıcı olarak havuzdan silinir ve analiz için kaydedilir.
Bu yaklaşım, Dolphin Anty veya AdsPower gibi anti-detect tarayıcılarında hesapların aktiviteye bağlı olarak "sağlık" durumuna sahip olduğu itibar sistemine benzer. Aynı mekanizma, parseliklerde IP adresleri için de mükemmel çalışır.
Kod: Python'da otomatik ayıklama ile ProxyPool
Aşağıda, hata metriklerini dikkate alarak proxy havuzunu yönetmek için çalışan bir sınıf iskeleti bulunmaktadır. Bu, herhangi bir parselik için requests, httpx veya Scrapy ile bağlanabilir, proxy alma mantığını pool.get_proxy() çağrısı ile değiştirebilirsiniz.
import time
import random
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class ProxyStats:
address: str
score: int = 100
quarantine_until: float = 0.0
total_requests: int = 0
total_success: int = 0
consecutive_timeouts: int = 0
is_dead: bool = False
@property
def success_rate(self) -> float:
if self.total_requests == 0:
return 1.0
return self.total_success / self.total_requests
class ProxyPool:
def __init__(self, proxies: list[str],
min_score: int = 30,
dead_score: int = 10,
quarantine_seconds: int = 1800):
self.stats = {p: ProxyStats(address=p) for p in proxies}
self.min_score = min_score
self.dead_score = dead_score
self.quarantine_seconds = quarantine_seconds
def _is_available(self, stats: ProxyStats) -> bool:
if stats.is_dead:
return False
if stats.quarantine_until > time.time():
return False
return True
def get_proxy(self) -> Optional[str]:
available = [s for s in self.stats.values() if self._is_available(s)]
if not available:
return None
# skora göre sıralıyoruz, en üst %30'dan rastgele alıyoruz, böylece bir IP'yi aşırı yüklemiyoruz
available.sort(key=lambda s: s.score, reverse=True)
top_pool = available[:max(1, len(available) // 3)]
return random.choice(top_pool).address
def report_success(self, proxy: str):
s = self.stats[proxy]
s.total_requests += 1
s.total_success += 1
s.consecutive_timeouts = 0
s.score = min(100, s.score + 2)
def report_timeout(self, proxy: str):
s = self.stats[proxy]
s.total_requests += 1
s.consecutive_timeouts += 1
s.score -= 15
if s.consecutive_timeouts >= 3:
self._quarantine(s)
self._check_dead(s)
def report_blocked(self, proxy: str, captcha: bool = False):
s = self.stats[proxy]
s.total_requests += 1
s.score -= 20 if captcha else 25
self._quarantine(s)
self._check_dead(s)
def _quarantine(self, s: ProxyStats):
if s.score < self.min_score:
s.quarantine_until = time.time() + self.quarantine_seconds
def _check_dead(self, s: ProxyStats):
if s.score <= self.dead_score:
s.is_dead = True
def stats_report(self) -> list[dict]:
return [
{
"proxy": s.address,
"score": s.score,
"success_rate": round(s.success_rate, 2),
"dead": s.is_dead,
}
for s in self.stats.values()
]
Gerçek bir parselik içinde report_success, report_timeout ve report_blocked çağrıları, her HTTP isteğinden sonra yanıt işleyicisine doğrudan yerleştirilir. requests ile entegrasyon örneği:
import requests
def fetch(url: str, pool: ProxyPool):
proxy = pool.get_proxy()
if not proxy:
raise RuntimeError("Havuzda mevcut proxy yok")
proxies = {"http": proxy, "https": proxy}
try:
resp = requests.get(url, proxies=proxies, timeout=8)
except requests.exceptions.Timeout:
pool.report_timeout(proxy)
return None
if resp.status_code in (403, 429):
pool.report_blocked(proxy)
return None
if "captcha" in resp.text.lower():
pool.report_blocked(proxy, captcha=True)
return None
pool.report_success(proxy)
return resp
Bu yaklaşım, manuel izleme yükünü azaltır: bir kez eşikleri ayarlarsınız ve ardından havuz kendiliğinden "iyileşir", ölü adresleri dışarı atar ve geçici olarak askıya alınanları karantinadan geri alır.
IP yasaklama için eşik değerleri
Evrensel sayılar yoktur - eşikler platforma ve anti-botun agresifliğine bağlıdır. Ancak, Wildberries, Ozon ve Avito parseliklerinde pratikte iyi çalışan bazı referanslar vardır:
- Başarı oranı %70'in altında 30-50 istekte - mevcut skor hala kritik olmasa bile IP'yi silmek için bir neden.
- Arka arkaya 3 zaman aşımı - neredeyse her zaman proxy'nin fiziksel olarak erişilemez veya aşırı yüklü olduğunu gösterir, aktif havuzda tutmanın anlamı yoktur.
- 20 istekte 1'den fazla CAPTCHA - IP zaten anti-bot tarafından şüpheli hale geldi, istek sıklığını azaltmak veya adresi değiştirmek daha iyidir.
- Yanıt süresi havuz medyanesinin 2 katı - bozulma sinyali, kritik değil ama seçimde önceliği düşürmek için bir neden.
30-60 dakika karantina genellikle veri merkezi ve yerel proxy'ler için yeterlidir, böylece anti-bot geçici şüpheli aktiviteyi "unutur". Mobil proxy'lerde durum farklıdır: burada IP, operatör tarafından hücre değiştiğinde değişir, bu nedenle karantina süresi daha kısa olabilir - 10-15 dakika, çünkü rotasyondan sonra bu fiziksel olarak farklı bir adres olur.
Healthcheck ve arka planda rotasyon
Reaktif ayıklamanın (parselik akışındaki hata olaylarına dayalı) yanı sıra, arka planda bir healthcheck çalıştırmak da faydalıdır - birkaç dakikada bir proxy'yi hafif isteklerle nötr bir URL'ye (örneğin, httpbin.org/ip) kontrol eden ayrı bir süreç ve proxy, Wildberries veya Ozon'a gerçek bir istekte bulunmadan önce havuzun istatistiklerini günceller.
import threading
def healthcheck_loop(pool: ProxyPool, interval: int = 300):
while True:
for proxy in list(pool.stats.keys()):
try:
r = requests.get(
"https://httpbin.org/ip",
proxies={"http": proxy, "https": proxy},
timeout=5
)
if r.status_code == 200:
pool.report_success(proxy)
else:
pool.report_blocked(proxy)
except requests.exceptions.RequestException:
pool.report_timeout(proxy)
time.sleep(interval)
threading.Thread(target=healthcheck_loop, args=(pool,), daemon=True).start()
Bu arka plan süreci özellikle önemlidir, eğer havuz büyükse (yüzlerce IP) ve parselik sürekli değil, partiler halinde yapılıyorsa - healthcheck olmadan bazı proxy'ler "bozulmayı" bekleyebilir ve parseli başlatmanın ilk dakikaları canlı ayıklama için harcanır, bunun yerine hemen kontrol edilen adreslerle çalışmak yerine.
Pazar yerleri için hangi proxy türünü seçmeli
Proxy türünün seçimi, ayıklama sıklığını ve eşiklerin ne kadar agresif olacağını doğrudan etkiler. Wildberries ve Ozon'da kararlı parselik için, anti-bot davranış kalıplarını ve alt ağın itibarını analiz ettiğinden, en iyi performansı yerel proxy'ler gösterir - bunların IP'leri gerçek ev interneti sağlayıcılarına aittir ve anti-bot bunları alt ağlar üzerinden topluca yasaklama olasılığı çok daha düşüktür.
Daha basit ve daha az korumalı kaynaklar (örneğin, Avito'dan kamu verilerini toplama veya basit vitrinlerde fiyat izleme) için genellikle veri merkezi proxy'leri yeterlidir - bunlar daha hızlı ve daha ucuzdur, bu da büyük istek hacimlerinde kritik öneme sahiptir, ancak biraz daha sık yasaklanırlar, bu nedenle ayıklama eşiklerini daha katı yapmak gerekir.
| Proxy Türü | Ayıklama Hızı | Ne Zaman Kullanılmalı |
|---|---|---|
| Veri Merkezi | Yüksek, alt ağlar topluca yasaklanır | Basit vitrinler, büyük hacimler, düşük koruma |
| Yerel | Orta, IP'ler noktasal olarak yasaklanır | Wildberries, Ozon, anti-bot olan siteler |
| Mobil | Düşük, IP otomatik olarak operatör tarafından değişir | Sıkı korumalı kaynaklar, yüksek frekanslı parselik |
Pratikte birçok ekip hibrit bir havuz kullanır: isteklerin ana kısmı yerel IP'ler üzerinden yapılır ve kitlesel yasaklamalarda mobil proxy'ler "acil" yedek olarak devreye alınır, çünkü IP değişimi hücresel ağ rotasyonu ile doğal olarak gerçekleşir ve manuel müdahale gerektirmez.
Sonuç
Ayıklama sistemi olmayan bir proxy havuzu kaçınılmaz olarak bozulur ve ne kadar uzun süre temizlenmeden çalışırsa, parselik o kadar çok kaynağı ölü IP'ler üzerinde israf eder. HTTP kodları, zaman aşımı, CAPTCHA ve başarı oranını dikkate alan bir skorlama modeli, sorunlu adresleri otomatik olarak tespit etmeyi ve havuzu manuel kontrol olmadan çalışır durumda tutmayı sağlar. Bu makaledeki kod, herhangi bir yığın için uyarlanabilir - requests, httpx, Scrapy veya kendi asenkron parseliğiniz için.
Eğer pazar yerleri için bir havuz oluşturuyorsanız ve yasaklama sıklığını başlangıçta azaltmak istiyorsanız, yerel proxy'lere göz atmanızı öneririz - bunlar, normal veri merkezi adreslerine kıyasla Wildberries ve Ozon gibi korumalı platformlarda belirgin şekilde daha yüksek bir başarı oranı sağlar.