Bir scraper'ın günlüğünde en sık görülen satırlar başarılı 200 yanıtları değil, arada bir beliren 403, 429 ve 503 kodlarıdır. Bu kodların her biri farklı bir sorunu anlatır ve her biri farklı bir tepki gerektirir. Hepsine aynı şekilde "üç kez yeniden dene" diye yaklaşan bir betik, kalıcı bir engeli zorlayıp durumu kötüleştirir ya da birkaç saniye bekleyince düzelecek geçici bir sorunda veriyi boşuna kaybeder.
Bu yazıda HTTP durum kodlarının nasıl okunacağını, scraping'de en çok karşılaşılan 403, 407, 429 ve 503 kodlarının ne anlama geldiğini ve arkalarındaki olası nedenleri anlatıyoruz. Ardından 502, 504 ve bağlantı hatalarını, Retry-After başlığının kullanımını ve hangi kodda yeniden denenip hangisinde durulması gerektiğini tek bir tabloda topluyoruz. Sonunda bu kararları uygulayan, denenmiş bir Python örneği var.
HTTP durum kodları nasıl okunur?
Her HTTP yanıtı üç haneli bir durum koduyla başlar. İlk hane, yanıtın sınıfını belirler. Kodların tanımları RFC 9110'un 15. bölümünde yer alır; MDN'deki durum kodları listesi de her kod için kısa açıklamalar ve örnekler verir.
| Sınıf | Anlamı | Scraping'deki karşılığı |
|---|---|---|
1xx | Bilgi, istek sürüyor | Pratikte görmezsiniz |
2xx | Başarılı | Sayfa geldi, ama içeriğini yine de kontrol edin |
3xx | Yönlendirme | Adres değişti veya giriş sayfasına yönlendirildiniz |
4xx | İstemci tarafı sorun | İsteğinizde, kimliğinizde veya hızınızda bir sorun var |
5xx | Sunucu tarafı sorun | Sunucu, ağ geçidi veya proxy isteği tamamlayamadı |
Scraping açısından en önemli ayrım şudur: 4xx kodlarının çoğu, aynı isteği aynen tekrar gönderdiğinizde yine aynı sonucu verir. İsteğinizde bir şeyi değiştirmeniz gerekir. 5xx kodlarının çoğu ise geçicidir ve bir süre bekledikten sonra aynı istek başarılı olabilir. 429 bu kuralın istisnasıdır: bir 4xx kodudur ama beklemeyle düzelir.
Bir de koddan bağımsız bir uyarı: 200 görmek, istediğiniz veriyi aldığınız anlamına gelmez. Bot koruma sistemleri doğrulama sayfasını çoğu zaman 200 koduyla döndürür. Yanıtı başarılı saymadan önce sayfada beklediğiniz bir öğenin (ürün başlığı, fiyat alanı) bulunduğunu kontrol edin.
403 Forbidden ne anlama gelir?
403, sunucunun isteğinizi anladığını ama yerine getirmeyi reddettiğini söyler. RFC 9110'a göre sunucu, bu kararın nedenini açıklamak zorunda değildir. Kimlik doğrulaması eksik olduğunda kullanılan 401 Unauthorized'dan farkı, 403'te kimlik bilgisi eklemenin genellikle sonucu değiştirmemesidir.
Scraping'de 403 almanın olası nedenleri:
- IP itibarı veya IP türü. Veri merkezi adreslerinden gelen trafiği kısıtlayan siteler, bu adreslere doğrudan
403döner. - Coğrafi kısıtlama. Site yalnızca belirli ülkelerden erişime izin veriyordur.
- Eksik veya tutarsız header. Kütüphanenin varsayılan
User-Agentdeğeri veya bir tarayıcıda hiç görülmeyen header kombinasyonu. - Web uygulama güvenlik duvarı (WAF) kuralı. İstek, bir güvenlik kuralına takılmıştır.
- Önceki trafiğiniz nedeniyle engelleme. Hız sınırını uzun süre aşan bir IP adresi, bir süre sonra
429yerine403almaya başlayabilir. - Gerçekten yetki gerektiren sayfa. Giriş yapılmadan erişilemeyen bir yol.
Yapılacak: Aynı isteği hemen tekrar göndermeyin. Adresi aynı IP ile gerçek bir tarayıcıda açmayı deneyin. Tarayıcıda açılıyorsa sorun isteğinizin kendisindedir (header, hız); açılmıyorsa IP veya konumdadır. Engellenmenin nedenlerini ve meşru çözümlerini Web Scraping'de Engellenmeden Veri Toplama Yöntemleri yazımızda ayrıntılı anlattık.
407 Proxy Authentication Required ne anlama gelir?
407, hedef siteden değil proxy sunucusundan gelir. Proxy, isteği hedefe iletmeden önce kimliğinizi kanıtlamanızı istiyor demektir. Bu yüzden 407 gördüğünüzde hedef sitenin kurallarıyla değil, proxy bağlantınızla ilgilenmeniz gerekir.
Olası nedenler:
- Kullanıcı adı veya şifre yanlış.
- Şifrede
@,:veya/gibi özel karakterler var ve proxy adresinin içinde kodlanmamış (@→%40). - IP whitelist yöntemi kullanılıyor ama bağlantının çıktığı IP adresi listede değil.
- Kütüphane, adresteki kimlik bilgisini proxy'ye göndermiyor.
- Hesaptaki bakiye veya trafik hakkı bitmiş.
Kütüphaneler 407'yi farklı biçimlerde gösterir. HTTPS isteklerinde proxy tüneli kurulamadığı için çoğu zaman bir yanıt nesnesi değil, bir istisna alırsınız: Python Requests ProxyError, HTTPX ProxyError fırlatır; Node.js'te Axios ise 407 durum kodlu bir hata döndürür. Kütüphane farklarını Node.js'te Proxy Kullanımı yazımızda denenmiş örneklerle gösterdik.
Yapılacak: Yeniden denemeyin, yapılandırmayı düzeltin. curl -v çıktısında Proxy-Authorization başlığının gönderilip gönderilmediğine bakın; komutun kendisi cURL ile Proxy Nasıl Kullanılır? yazımızda. İki kimlik doğrulama yöntemini ve 407'nin teşhisini Proxy Kimlik Doğrulama: User:Pass ve IP Whitelist yazımızda adım adım anlattık.
429 Too Many Requests ne anlama gelir?
429, belirli bir süre içinde çok fazla istek gönderdiğinizi söyler. Kod RFC 6585'in 4. bölümünde tanımlanır ve sunucunun yanıtla birlikte bir Retry-After başlığı göndererek ne kadar beklemeniz gerektiğini bildirebileceğini belirtir.
Hız sınırının neye göre sayıldığı siteden siteye değişir:
- IP adresine göre: Aynı adresten gelen istekler toplanır.
- Oturuma veya çereze göre: Aynı oturumdaki istekler toplanır; IP değiştirmek sayacı sıfırlamaz.
- API anahtarına göre: Resmi API'lerde sınır genellikle anahtara bağlıdır.
- Uç noktaya göre: Arama sayfası gibi ağır uç noktalarda sınır, ürün sayfalarından daha düşüktür.
Bazı API'ler kalan hakkınızı X-RateLimit-Remaining ve X-RateLimit-Reset gibi başlıklarla bildirir. Bu başlıkların adları standart değildir ve servisten servise değişir; kullandığınız API'nin belgesine bakın.
Yapılacak: Retry-After varsa o süre kadar bekleyin. Yoksa üstel geri çekilme uygulayın: ilk denemede 1 saniye, sonra 2, 4, 8 saniye, her birine rastgele bir bileşen ekleyerek. Aynı zamanda eşzamanlılığı düşürün; bekleyip aynı hızla devam ederseniz kısa süre sonra yine 429 alırsınız.
503 Service Unavailable ne anlama gelir?
503, sunucunun şu an isteği karşılayamadığını, ancak durumun geçici olduğunu söyler. Bakım çalışması, aşırı yük veya arkadaki uygulama sunucusunun çökmesi tipik nedenlerdir. RFC 9110'a göre sunucu, ne zaman tekrar deneneceğini Retry-After ile bildirebilir.
Scraping'de 503'ün iki farklı yüzü vardır:
- Gerçek bir yoğunluk veya bakım. Site herkese
503dönüyordur. Beklemek dışında yapılacak bir şey yoktur. - Bot korumasının geçici engeli. Bazı koruma sistemleri, şüpheli buldukları trafiğe bir doğrulama sayfasıyla birlikte
503döner. Sayfa gövdesinde bir doğrulama ekranı varsa sorun sunucu yükü değil, trafiğinizin kendisidir.
Yapılacak: Gövdeye bakarak iki durumu ayırın. Gerçek yoğunlukta Retry-After veya üstel geri çekilmeyle bekleyin. Doğrulama sayfası görüyorsanız, yeniden denemek yerine hızınızı ve istemci kimliğinizi gözden geçirin. Tarayıcı otomasyonunda bu ekranların neden çıktığını Puppeteer ve CAPTCHA yazımızda anlattık.
502, 504 ve bağlantı hataları
Proxy kullanan bir scraper, hedef siteden gelen yanıtların yanında proxy'nin kendisinden gelen hatalarla da karşılaşır. Bu kodlar, sorunun zincirin hangi halkasında olduğunu anlamak için önemlidir.
500 Internal Server Error: Hedef uygulamada bir hata oluştu. Bazen belirli bir sayfaya özgüdür. Bir iki kez yeniden denenebilir; sürekli tekrarlanıyorsa o adresi atlayın.502 Bad Gateway: Aradaki bir ağ geçidi (proxy, CDN veya reverse proxy) arkadaki sunucudan geçerli bir yanıt alamadı. Proxy bağlamında, proxy'nin hedefe ulaşamadığı anlamına gelebilir. Kısa bir beklemeyle yeniden denenir.504 Gateway Timeout: Ağ geçidi, arkadaki sunucudan zamanında yanıt alamadı. Hedef yavaşsa veya proxy'nin çıkış noktası uzaksa görülür. Yeniden denenir.408 Request Timeout: Sunucu, isteğin tamamlanmasını beklerken zaman aşımına uğradı. Yeniden denenir.- Bağlantı hataları: Kod yoktur, istemci bir istisna fırlatır. Bağlantı reddedildi (
ECONNREFUSED), bağlantı sıfırlandı (ECONNRESET), zaman aşımı, alan adı çözülemedi (ENOTFOUND) gibi. Adres veya port yanlışsa hiçbir deneme düzeltmez; ağ kopması gibi geçici durumlarda yeniden deneme işe yarar. - CDN'e özgü kodlar: Bazı CDN'ler
520-526aralığında standart dışı kodlar kullanır. Bunlar genellikle CDN ile sitenin kendi sunucusu arasındaki bağlantı sorunlarını anlatır.
404 Not Found ve 410 Gone ise sayfanın olmadığını söyler. Yeniden denemek yerine adresi listenizden çıkarın; aniden çok sayıda 404 görüyorsanız sitenin adres yapısı değişmiş olabilir.
Retry-After nasıl kullanılır?
Retry-After başlığı iki biçimde gelebilir:
- Saniye cinsinden sayı:
Retry-After: 120→ 120 saniye bekleyin. - HTTP tarihi:
Retry-After: Wed, 16 Sep 2026 07:28:00 GMT→ bu tarihten sonra deneyin.
Doğru kullanım için dört kural:
- Başlık varsa tahmin etmeyin, uyun. Sunucunun verdiği süre, sizin hesaplayacağınız geri çekilmeden daha doğrudur.
- Üst sınır koyun. Başlık birkaç saat gibi uzun bir süre söylüyorsa, betiğinizin o süre boyunca asılı kalması yerine adresi daha sonraki bir çalıştırmaya bırakın.
- Beklemeyi yalnızca o isteğe değil, o siteye uygulayın.
429alan bir isteği beklettiğiniz sırada aynı siteye paralel olarak başka istekler gönderiyorsanız sınır aşılmaya devam eder. - Tarih biçimini de ayrıştırın. Yalnızca sayı bekleyen kod, tarih biçimiyle gelen başlığı yok sayar. İki biçimi de işleyen bir Python fonksiyonunu Web Scraping'de Engellenmeden Veri Toplama Yöntemleri yazımızda paylaştık.
Hangi kodda yeniden denenir, hangisinde durulur?
| Kod | Anlamı | Scraping'deki olası neden | Yapılacak |
|---|---|---|---|
200 | Başarılı | Sayfa geldi, ama doğrulama ekranı olabilir | İçerikte beklenen öğeyi kontrol et |
301 / 302 | Yönlendirme | Adres değişti veya giriş sayfasına yönlendirme | Yönlendirmeyi izle; giriş sayfasıysa oturumu kontrol et |
400 | Hatalı istek | Bozuk parametre veya gövde | Durdur, isteği düzelt |
401 | Kimlik gerekli | Giriş veya API anahtarı eksik | Durdur, kimlik bilgisini ekle |
403 | Reddedildi | IP türü, konum, header, WAF kuralı | Durdur, teşhis et |
404 / 410 | Sayfa yok | Silinmiş ürün, değişen adres yapısı | Listeden çıkar |
407 | Proxy kimliği gerekli | Yanlış şifre, kodlanmamış karakter, whitelist | Durdur, proxy ayarını düzelt |
408 | İstek zaman aşımı | Yavaş bağlantı | Yeniden dene |
429 | Çok fazla istek | Hız sınırı aşıldı | Retry-After kadar bekle, hızı düşür |
500 | Sunucu hatası | Hedef uygulamada hata | Birkaç kez dene, sonra atla |
502 | Hatalı ağ geçidi | Proxy veya CDN hedefe ulaşamadı | Kısa beklemeyle yeniden dene |
503 | Hizmet yok | Yoğunluk, bakım veya koruma sayfası | Gövdeye bak; Retry-After ile bekle |
504 | Ağ geçidi zaman aşımı | Hedef yavaş, çıkış noktası uzak | Yeniden dene, gerekirse daha yakın konum |
| Bağlantı hatası | Yanıt yok | Ağ kopması, yanlış adres veya port | Geçiciyse dene; kalıcıysa yapılandırmayı düzelt |
Örnek: koda göre karar veren yeniden deneme
Aşağıdaki örnek HTTPX'in asenkron istemcisiyle çalışır. 408, 429 ve 5xx kodlarında Retry-After başlığına uyar, başlık yoksa rastgele bileşenli üstel geri çekilme uygular. 403, 404 ve 407 gibi yeniden denemenin sonucu değiştirmeyeceği kodlarda ise ayrı bir istisna fırlatarak durur. Proxy kimlik doğrulama hatası (HTTPS isteklerinde ProxyError olarak gelir) de bu gruba girer.
import asyncio
import random
import httpx
RETRY_STATUS = {408, 429, 500, 502, 503, 504}
STOP_STATUS = {400, 401, 403, 404, 407, 410}
class StopScraping(Exception):
"""Yeniden denemenin sonucu değiştirmeyeceği durumlar."""
def backoff(response, attempt, base=1.0, cap=60.0):
retry_after = response.headers.get("Retry-After") if response is not None else None
if retry_after and retry_after.isdigit():
return min(int(retry_after), cap)
return min(cap, base * 2**attempt) * random.uniform(0.5, 1.0)
async def fetch(client, url, attempts=5):
for attempt in range(attempts):
response = None
try:
response = await client.get(url)
except httpx.ProxyError as exc:
raise StopScraping(f"Proxy hatası (kimlik bilgilerini kontrol edin): {exc}") from exc
except httpx.TransportError:
pass # bağlantı kopması, zaman aşımı: yeniden denenebilir
else:
status = response.status_code
if status < 400:
return response
if status in STOP_STATUS:
raise StopScraping(f"{url}: HTTP {status}, yeniden denenmeyecek")
if status not in RETRY_STATUS:
return response
await asyncio.sleep(backoff(response, attempt))
raise RuntimeError(f"{url}: {attempts} denemede sonuç alınamadı")
async def main():
proxy = "http://kullanici:parola@pr.proxynet.io:8000"
async with httpx.AsyncClient(proxy=proxy, timeout=20, follow_redirects=True) as client:
urls = ["https://ornek.com/urun/1", "https://ornek.com/urun/2"]
results = await asyncio.gather(*(fetch(client, u) for u in urls), return_exceptions=True)
for url, result in zip(urls, results):
print(url, result if isinstance(result, Exception) else result.status_code)
asyncio.run(main())Örneği iki noktada kendi işinize göre genişletin. Birincisi, asyncio.gather bütün adresleri aynı anda başlatır; gerçek bir işte aynı siteye aynı anda giden istek sayısını asyncio.Semaphore ile sınırlayın. İkincisi, Retry-After HTTP tarihi olarak da gelebilir; bu biçimi de ayrıştırmanız gerekiyorsa yukarıda bağlantısını verdiğimiz fonksiyonu kullanın. HTTPX ve diğer Python kütüphanelerinin farkları HTTPX, Requests ve AIOHTTP yazımızda.
Hataları kaydetmek ve izlemek
Durum kodlarını yalnızca anlık karar için değil, işin sağlığını izlemek için de kullanın. Her çalıştırmada şu sayıları kaydetmek, sorunları erken fark etmenizi sağlar:
- Koda göre yanıt sayısı:
429oranı artıyorsa hızınız fazla;403oranı artıyorsa IP veya header tarafında bir değişiklik var. - Site ve uç noktaya göre dağılım: Sorun tek bir sitede mi, bütün sitelerde mi? Bütün sitelerde aynı anda artan hatalar genellikle proxy veya ağ tarafını gösterir.
- Yeniden deneme sayısı ve toplam bekleme süresi: Yeniden denemeler işin süresinin önemli bir kısmını alıyorsa eşzamanlılık ayarı yanlıştır.
200ama beklenen öğesi olmayan yanıtlar: Sessiz veri kaybının tek göstergesi budur.
Kullanım senaryoları
- Günlük fiyat takibi:
404alan ürünler listeden çıkarılır,429alan siteler için ertesi çalıştırmada eşzamanlılık düşürülür. Genel kurgu veri kazıma çözümü sayfamızda. - Çok sayıda siteden katalog toplama: Tek bir sitede artan
403oranı o site için ayrı teşhis gerektirir; yük dağıtımı için Rotating Proxy kullanılır. - Oturum gerektiren kendi paneliniz:
302ile giriş sayfasına yönlendirme, oturum ortasında IP değiştiğini gösterebilir; oturum boyunca aynı IP için Sticky Proxy tercih edilir. - Yeni proxy kurulumu: İlk isteklerde
407veyaProxyErrorgörüyorsanız sorun hedefte değil, kimlik bilgilerindedir.
Sık yapılan hatalar
- Her hatada aynı sayıda yeniden denemek.
403ve407'yi tekrar etmek sonucu değiştirmez, yalnızca gereksiz trafik üretir. Retry-Afterbaşlığını okumamak. Sunucu size ne kadar beklemeniz gerektiğini söylemişken kendi tahmininizle erken dönmek.- Geri çekilmeye rastgele bileşen eklememek. Aynı anda başarısız olan yüzlerce istek, aynı anda yeniden denenir ve yeni bir yığılma oluşturur.
200yanıtını içeriğe bakmadan kabul etmek. Doğrulama sayfaları sessizce boş veri üretir.407'yi hedef sitenin hatası sanmak. Hedefi değil, proxy yapılandırmanızı kontrol etmeniz gerekir.- Yeniden denemeye üst sınır koymamak. Kalıcı bir sorunda sonsuza kadar dönen bir döngü, hem kaynaklarınızı hem hedef siteyi yorar.
Karar rehberi
| Gördüğünüz | İlk yapılacak |
|---|---|
429 | Retry-After kadar bekleyin, eşzamanlılığı düşürün |
503 ve normal hata sayfası | Bekleyin ve yeniden deneyin |
503 ve doğrulama sayfası | Durun, hızı ve istemci kimliğini gözden geçirin |
403 | Aynı IP ile tarayıcıda deneyin, nedeni teşhis edin |
407 veya ProxyError | Proxy kullanıcı adı, şifre ve whitelist'i kontrol edin |
502 / 504 | Kısa beklemeyle yeniden deneyin; sürerse çıkış konumunu değiştirin |
404 / 410 | Adresi listeden çıkarın |
200 ama veri yok | Doğrulama sayfası veya dinamik yükleme olup olmadığını kontrol edin |
Sık sorulan sorular
403 ile 401 arasındaki fark nedir?
401 Unauthorized, isteğin kimlik doğrulaması gerektirdiğini ve geçerli bir kimlik bilgisi göndermediğinizi söyler. 403 Forbidden ise sunucunun isteği anladığını ama kimlik bilgisinden bağımsız olarak reddettiğini söyler. 401'de kimlik eklemek çözüm olabilir, 403'te genellikle olmaz.
407 hatası neden hedef siteden değil de proxy'den gelir?
Çünkü istek hedefe hiç ulaşmamıştır. Proxy, bağlantıyı iletmeden önce kimliğinizi doğrular ve doğrulama başarısız olursa yanıtı kendisi verir. Bu yüzden 407 hedef sitenin kurallarıyla ilgisizdir.
429 aldıktan sonra IP değiştirmek çözüm mü?
Hız sınırı IP'ye göre sayılıyorsa geçici olarak sonuç verebilir, ama sorunun kaynağı olan hızı değiştirmez ve sınır oturum veya hesap bazındaysa hiç işe yaramaz. Doğru tepki beklemek ve hızı düşürmektir; rotasyon, başından beri yükü dağıtmak için planlanmalıdır.
Retry-After başlığı yoksa ne kadar beklemeliyim?
Üstel geri çekilme uygulayın: birkaç saniyeyle başlayıp her denemede ikiye katlayın, bir üst sınır koyun ve her beklemeye rastgele bir bileşen ekleyin. Birkaç denemeden sonra hâlâ başarısızsa adresi sonraki bir çalıştırmaya bırakın.
503 hatası sitenin çöktüğü anlamına mı gelir?
Her zaman değil. Bakım, geçici yoğunluk veya bot korumasının verdiği bir engel de olabilir. Yanıt gövdesine bakın: bir bakım mesajı mı, genel bir hata sayfası mı, yoksa doğrulama ekranı mı?
Proxy kullanırken 502 hatası alıyorum. Sorun nerede?
502, aradaki ağ geçidinin arkadaki sunucudan geçerli yanıt alamadığını söyler. Proxy bağlamında, proxy'nin hedefe ulaşamadığını veya hedefin bağlantıyı kestiğini gösterebilir. Aynı adresi proxy olmadan deneyin: proxy'siz çalışıyorsa proxy'nin çıkış noktasında, proxy'siz de çalışmıyorsa hedef sitede bir sorun vardır.
Özetle
HTTP durum kodları scraper'ınıza ne yapması gerektiğini söyler: 429 ve 503 beklemeyi, 403 teşhisi, 407 proxy yapılandırmasını düzeltmeyi, 404 adresi listeden çıkarmayı ister. Retry-After başlığı varsa ona uyun, yoksa rastgele bileşenli üstel geri çekilme kullanın ve her yeniden denemeye bir üst sınır koyun. 200 yanıtlarında da içeriği kontrol etmeyi ihmal etmeyin. Veri toplama işleriniz için uygun proxy türlerini proxy hizmetlerimizde bulabilirsiniz.




