Bir fiyat takip betiği ilk gün sorunsuz çalışır, ikinci gün yarı yarıya boş sayfa döner, üçüncü gün her isteğe 403 alır. Bu tablo scraper yazan hemen herkesin başından geçer ve ilk tepki genellikle "daha çok IP" ya da "daha iyi gizlenme" arayışı olur. Oysa engellemelerin büyük kısmının nedeni daha sıradandır: saniyede onlarca istek, gerçek bir tarayıcıyla hiç eşleşmeyen header'lar, tek bir IP adresine yığılan yük ve sitenin açıkça yazdığı kuralların okunmaması.
Bu yazıda web scraping (veri kazıma) yapan araçların neden engellendiğini, engellenmenin belirtilerini ve bu belirtilerin arkasındaki nedenleri anlatıyoruz. Ardından istek hızını ayarlamayı, header'ları tutarlı tutmayı, IP rotasyonunun ne zaman gerçekten gerektiğini, oturum isteyen işlerde sabit IP kullanmayı ve robots.txt ile site şartlarını ele alıyoruz. Bu yazı bir "koruma atlatma" rehberi değildir: başlıktaki "engellenmeden", siteye zarar vermeden ve kurallarına uyarak engele takılmamak anlamındadır.
Siteler scraper'ı neden engeller?
Bir sitenin otomatik trafiği sınırlamasının arkasında genellikle kötü niyet varsayımı değil, somut maliyetler vardır:
- Sunucu yükü. Saniyede yüzlerce istek gönderen tek bir betik, küçük bir e-ticaret sitesinin gerçek ziyaretçilerine ayrılan kaynağı tüketebilir. Veritabanı sorgusu gerektiren arama ve filtre sayfalarında bu etki katlanır.
- Bant genişliği ve altyapı maliyeti. Her istek, sitenin sunucu ve CDN faturasına yansır.
- İçerik ve ticari veri koruması. Fiyat, stok ve ilan verisi rakipler tarafından toplu çekildiğinde site sahibi bunu kısıtlamak isteyebilir.
- Güvenlik. Kaba kuvvetle giriş denemesi, kart doğrulama ve stok toplama gibi saldırılar da otomatik trafikle yapılır. Koruma sistemleri bu trafikle meşru bir scraper'ı ilk bakışta ayırt edemez.
Bu kararların çoğu sitenin kendi kodunda değil, önündeki bot yönetim katmanında verilir. CDN'ler ve güvenlik servisleri her isteği hız, IP itibarı, header tutarlılığı ve davranış gibi sinyallerle puanlar. Bu katmanın bot trafiğini nasıl sınıflandırdığına bir örnek Cloudflare Precursor yazımızda.
Engellenmenin belirtileri nelerdir?
Engellenme her zaman açık bir hata mesajıyla gelmez. Scraper'ınızın ürettiği veride şu belirtilerden birini görüyorsanız sorun büyük olasılıkla budur:
403 Forbidden: İstek anlaşıldı ama reddedildi. IP itibarı, eksik header veya coğrafi kısıtlama olabilir.429 Too Many Requests: Hız sınırını aştınız. Çoğu zamanRetry-Afterbaşlığıyla ne kadar beklemeniz gerektiği söylenir.503 Service Unavailable: Sunucu gerçekten yoğun olabilir ya da bot koruma sistemi geçici olarak bu yanıtı veriyor olabilir.200ama doğrulama sayfası: Durum kodu başarılı görünür, ama sayfa içeriği ürün listesi yerine bir doğrulama ekranıdır.200ama boş veya eksik içerik: Seçicileriniz hiçbir şey bulamaz. Bu belirti engellemeden de, sayfanın JavaScript ile yüklenmesinden de kaynaklanabilir.- Giriş sayfasına yönlendirme: Oturumunuz sonlandırılmıştır, çoğu zaman oturum ortasında IP değişikliği yüzünden.
- Yavaşlayan yanıtlar: Bazı sistemler isteği reddetmek yerine yanıtı bilerek geciktirir.
HTTP durum kodlarının her birini ve hangisinde yeniden denemeniz gerektiğini Scraping'de HTTP Hata Kodları yazımızda ayrıntılı anlattık. Boş içeriğin engelleme mi yoksa dinamik sayfa mı olduğunu anlamak için Statik ve Dinamik Sayfalar yazımıza bakabilirsiniz.
| Belirti | Olası neden | Meşru çözüm |
|---|---|---|
Kısa sürede çok sayıda 429 | İstek hızı sitenin sınırını aşıyor | Eşzamanlılığı düşürün, Retry-After kadar bekleyin |
İlk istekten itibaren 403 | Eksik header, IP'nin veri merkezine ait olması veya bölge kısıtı | Tutarlı header kullanın; hedef kitleye uygun IP türü ve konum seçin |
Bir süre sonra başlayan 403 | Tek IP'den yoğun trafik işaretlendi | Hızı düşürün, yükü zamana ve gerekirse IP'lere yayın |
| Doğrulama sayfası | Davranış veya IP itibarı şüpheli bulundu | Durun, hızı ve kapsamı gözden geçirin; API veya izin arayın |
200 ama boş içerik | Sayfa JavaScript ile yükleniyor ya da içerik gizlendi | Arka plandaki API isteğini bulun; gerekirse headless tarayıcı |
| Oturum aniden kapanıyor | Oturum ortasında IP değişti | Oturum boyunca sabit IP kullanın |
| Yanıtlar giderek yavaşlıyor | Sunucu yükü veya bilinçli geciktirme | İstek hızını düşürün, yoğun saatlerden kaçının |
| Sayfa içeriği gerçek tarayıcıdakinden farklı | Bota özel içerik veya konum farkı | Konumu doğrulayın; kendinizi tanıtan istemci kimliği kullanın |
İstek hızı: hız sınırına nasıl uyulur?
Engellenmenin en yaygın ve en kolay önlenen nedeni hızdır. Bir insan bir e-ticaret sitesinde birkaç saniyede bir sayfa açar; asyncio ile yazılmış bir scraper aynı sürede yüzlerce istek atabilir. RFC 6585, 429 Too Many Requests kodunu tam da bu durum için tanımlar ve sunucunun Retry-After başlığıyla ne kadar beklenmesi gerektiğini söyleyebileceğini belirtir.
Hızı kontrol altında tutmanın temel kuralları:
- Site başına eşzamanlılık sınırı koyun. Aynı alan adına aynı anda açık istek sayısını küçük tutun. Toplam eşzamanlılık yüksek olabilir, ama tek bir siteye düşen pay düşük kalmalıdır.
- İstekler arasına rastgele bekleme ekleyin. Tam olarak her 2 saniyede bir gelen istek, düzensiz aralıklardan daha dikkat çekicidir ve anlık yığılmaları önlemez.
429ve503aldığınızda yavaşlayın, hızlanmayın. Başarısız isteği hemen tekrar göndermek sorunu büyütür. Üstel geri çekilme (exponential backoff) kullanın.Retry-Afterbaşlığına uyun. Değer saniye cinsinden bir sayı ya da bir HTTP tarihi olabilir; MDN'deki açıklama iki biçimi de gösterir.- Gereksiz isteği hiç göndermeyin. Değişmemiş sayfaları tekrar indirmemek için
ETagveLast-Modifieddeğerlerini saklayıpIf-None-MatchveIf-Modified-Sincebaşlıklarıyla koşullu istek gönderin; sayfa değişmemişse sunucu gövdesiz304döner. - Sitemap'i kullanın. Bütün siteyi bağlantı bağlantı gezmek yerine sitenin
sitemap.xmldosyasındaki adreslerle başlayın. - Yoğun saatlerden kaçının. Hedef kitlenin sitede en yoğun olduğu saatlerde toplu çekim yapmayın.
Aşağıdaki Python fonksiyonu 429, 502, 503 ve 504 yanıtlarında Retry-After başlığına uyar; başlık yoksa rastgele bileşenli üstel geri çekilme uygular. 403 ve 404 gibi yanıtları ise yeniden denemez, çünkü tekrar göndermek sonucu değiştirmez:
import random
import time
from datetime import datetime, timezone
from email.utils import parsedate_to_datetime
import requests
RETRY_STATUS = {429, 502, 503, 504}
def retry_after_seconds(value):
"""Retry-After saniye ya da HTTP tarihi olabilir."""
if not value:
return None
if value.isdigit():
return int(value)
try:
when = parsedate_to_datetime(value)
except (TypeError, ValueError):
return None
return max(0.0, (when - datetime.now(timezone.utc)).total_seconds())
def polite_get(session, url, max_attempts=5, base=1.0, cap=60.0):
for attempt in range(max_attempts):
try:
response = session.get(url, timeout=20)
except (requests.ConnectionError, requests.Timeout):
response = None
if response is not None and response.status_code not in RETRY_STATUS:
return response # 200, 404, 403 gibi yanıtlar yeniden denenmez
wait = None
if response is not None:
wait = retry_after_seconds(response.headers.get("Retry-After"))
if wait is None:
wait = min(cap, base * 2**attempt) * random.uniform(0.5, 1.0)
time.sleep(min(wait, cap))
raise RuntimeError(f"{url}: {max_attempts} denemede yanıt alınamadı")Bu fonksiyonu bir sayfa listesi üzerinde, istekler arasına bekleme koyarak kullanmak yeterlidir:
session = requests.Session()
session.headers.update({
"User-Agent": "OrnekFiyatBotu/1.0 (+https://ornek.com/bot-hakkinda)",
"Accept-Language": "tr-TR,tr;q=0.9",
})
for url in urls:
response = polite_get(session, url)
if response.status_code == 403:
print("Erişim reddedildi, durup nedenini inceleyin:", url)
break
isle(response.text)
time.sleep(random.uniform(2, 5))Eşzamanlılığı hangi değere ayarlamanız gerektiğini ve hızı gerçekte neyin sınırladığını Concurrency ve Parallelism yazımızda anlattık.
Header'lar ve tutarlı istemci kimliği
Bir HTTP isteğinin header'ları, istemcinin kim olduğunu ve neyi kabul ettiğini söyler. Kütüphanelerin varsayılan header'ları bir tarayıcıdan çok farklıdır. Python Requests varsayılan olarak python-requests/2.x gibi bir User-Agent gönderir; birçok site bu değeri doğrudan reddeder.
Burada iki yaklaşım vardır ve ikisinin amacı farklıdır:
Kendinizi tanıtmak. Meşru tarayıcılar (crawler) User-Agent içinde botun adını ve hakkında bilgi verilen bir adres yazar: OrnekFiyatBotu/1.0 (+https://ornek.com/bot-hakkinda). Site yöneticisi trafiği görünce kimin gönderdiğini ve size nasıl ulaşacağını bilir; sorun varsa engellemek yerine iletişime geçebilir. robots.txt kurallarını da bu adla size özel yazabilir.
Tutarlılık. Hangi kimliği kullanırsanız kullanın, istek boyunca tutarlı olmalıdır. Tutarsızlık örnekleri:
- Her istekte rastgele değişen
User-Agent, ama aynı çerez ve aynı IP. - Chrome olduğunu söyleyen bir
User-Agent, ama Chrome'un her istekte gönderdiğiAccept,Accept-LanguageveSec-CH-UAheader'larının hiç olmaması. - Türkiye'deki bir siteye
Accept-Language: en-USile, ABD'den çıkan bir IP ile gelip Türkçe fiyat beklemek.
Tarayıcıların header dışında hangi sinyallerle tanındığını Tarayıcı Parmak İzi yazımızda anlattık. Bu sinyalleri sahteleyerek bot korumasını aşmaya çalışmak bu yazının önerisi değildir; amaç, istemcinizin ne olduğunu tutarlı biçimde söylemesidir.
IP çeşitliliği: rotasyon ne zaman gerekir?
Tek bir IP adresinden gelen yoğun trafik, hız sınırlarının en kolay uygulandığı birimdir. Bu yüzden "engellendim, IP değiştireyim" düşüncesi yaygındır. Ancak rotasyonun iki meşru amacı ve bir yanlış kullanımı vardır.
Meşru amaç 1: Yükü dağıtmak. Yüzlerce farklı sitenin herkese açık fiyat sayfalarını toplayan bir iş, bütün trafiği tek IP'den çıkardığında IP adresi kısa sürede kötü itibar kazanır ve hiçbir sitenin sınırını aşmasa bile genel itibar listelerinde işaretlenebilir. Trafiği farklı adreslere dağıtmak, her adrese düşen yükü gerçekçi seviyede tutar.
Meşru amaç 2: Konuma göre içeriği görmek. Fiyat, stok ve arama sonuçları ziyaretçinin ülkesine ve şehrine göre değişir. Farklı konumlardan çıkış yapmak, her pazarın gerçek görünümünü toplamanın tek yoludur.
Yanlış kullanım: Açık bir engeli aşmak. Site sizi hız sınırıyla uyardıysa, robots.txt ile o yolu yasakladıysa ya da şartlarında otomatik erişimi açıkça yasakladıysa, IP değiştirerek aynı hızda devam etmek sorunu çözmez; site sahibinin açıkça ifade ettiği bir tercihi yok saymak anlamına gelir.
Rotasyonun kurulumu için tek adres üzerinden her bağlantıda farklı çıkış IP'si veren Rotating Proxy kullanılabilir. Gerçek ev bağlantılarından çıkan adresler gereken işlerde Residential Proxy tercih edilir. Python'da rotasyonlu bir kurulumu Python ile Rotating Proxy yazımızda adım adım anlattık.
Oturum gereken yerde sticky IP
Her istekte IP değiştirmek her iş için doğru değildir. Şu işlerde IP adresinin bir süre sabit kalması gerekir:
- Giriş yapılan sayfalar. Kendi hesabınıza ait panelden rapor çekiyorsanız, oturumun ortasında IP değişikliği güvenlik kontrolünü tetikler ve oturum kapanır.
- Çok adımlı akışlar. Sepete ekleme, filtre seçimi veya sayfalama gibi sunucu tarafında durum tutan akışlar.
- Çerezle ilişkilendirilen ziyaretler. Aynı çerezle farklı ülkelerden gelen istekler tutarsız bir ziyaretçi görüntüsü oluşturur.
Bu işlerde Sticky Proxy belirli bir süre boyunca aynı çıkış IP'sini korur. Genel kural: bir oturum = bir IP; oturum bitince IP değişebilir.
robots.txt ve site şartları
Bir siteden veri toplamaya başlamadan önce iki belgeye bakılmalıdır.
robots.txt, sitenin botlara hangi yolları taramamalarını istediğini söyleyen dosyadır ve biçimi RFC 9309 ile standartlaşmıştır. Disallow ile kapatılan yolları taramamak, sitenin açıkça belirttiği tercihe uymaktır. Dosyanın nasıl okunacağını ve Python'da nasıl kontrol edileceğini robots.txt Dosyası Nedir, Nasıl Okunur? yazımızda anlattık.
Hizmet şartları ise otomatik erişimle ilgili hükümler içerebilir. Bazı siteler scraping'i tamamen yasaklar, bazıları belirli bir hızla sınırlar, bazıları da veri için resmi bir API sunar. Resmi API varsa neredeyse her zaman daha iyi yoldur: veri yapılandırılmış gelir, sayfa tasarımı değiştiğinde kodunuz bozulmaz ve erişiminiz sözleşmeye dayanır.
Kişisel veri içeren sayfalar ayrı bir dikkat gerektirir; Türkiye'de KVKK, Avrupa'da GDPR kapsamındaki yükümlülükler, veriyi nasıl topladığınızdan bağımsız olarak geçerlidir. Hukuki çerçeveyi Web Scraping Yasal mı? yazımızda ele aldık.
Bazı siteler, ziyaretçinin göremediği ama botların takıldığı gizli bağlantılar da yerleştirir. Görünür bağlantıları izleyen ve kapsamı dar tutulan bir tarayıcı bu tuzaklardan kendiliğinden uzak durur; mekanizmayı Honeypot Tuzakları yazımızda anlattık.
CAPTCHA çıkınca ne yapmalı?
Scraper'ın karşısına bir doğrulama ekranı çıkması, sitenin trafiğinizi şüpheli bulduğu anlamına gelir. Bu noktada CAPTCHA çözdürme servisleri ya da tespit atlatma eklentileri önerilmez; hem sitenin açık bir kontrolünü aşmaya çalışmak demektir hem de genellikle sorunun kaynağını gizler. Bunun yerine şu sırayla ilerleyin:
- Scraper'ı durdurun. Doğrulama ekranına istek göndermeye devam etmek IP'nin ve oturumun itibarını daha da düşürür.
- Hızı ölçün. Son dakikada aynı siteye kaç istek gönderdiğinizi kontrol edin.
- Header'ları gerçek bir tarayıcıyla karşılaştırın. Eksik veya çelişkili header var mı?
- Kapsamı gözden geçirin. robots.txt'nin kapattığı yolları veya gerekmeyen sayfaları tarıyor musunuz?
- Alternatif arayın. Resmi API, veri dışa aktarma seçeneği veya site sahibiyle doğrudan iletişim.
- Ancak bundan sonra daha düşük hızla ve tutarlı bir istemci kimliğiyle yeniden deneyin.
Tarayıcı otomasyonunda doğrulama ekranlarının neden çıktığını Puppeteer ve CAPTCHA yazımızda aynı teşhis mantığıyla anlattık.
Engellenince ne yapmalı? Teşhis listesi
- Engellemenin başladığı anı ve o andaki istek hızını biliyor musunuz?
- Yanıt kodu ne:
403,429,503mü, yoksa200ama doğrulama sayfası mı? Retry-Afterbaşlığı geldi mi ve uydunuz mu?- Aynı adres gerçek bir tarayıcıda, aynı IP ile açılıyor mu?
- Header'larınız tutarlı mı,
User-Agentkütüphanenin varsayılanı mı? - Taradığınız yollar robots.txt'de kapatılmış mı?
- Site şartları otomatik erişim hakkında ne diyor?
- Oturum gerektiren bir akışta IP değişiyor mu?
- Boş içerik, JavaScript ile yüklenen bir sayfadan mı kaynaklanıyor?
- Aynı veriyi sunan resmi bir API var mı?
Kullanım senaryoları
- Fiyat takibi: Günlük birkaç kez, sitemap'ten alınan ürün adresleri, koşullu isteklerle yalnızca değişen sayfalar. Kurgusu fiyat takibi çözümü sayfamızda.
- Pazar araştırması ve katalog toplama: Çok sayıda farklı sitenin herkese açık sayfaları, site başına düşük eşzamanlılık, yükü dağıtmak için rotasyon. Genel kurgu veri kazıma çözümü sayfamızda.
- Geniş tarama (crawl): Bağlantıları izleyen, robots.txt'ye uyan, alan adı başına kuyruk tutan bir tarayıcı. Ölçekleme tarafı web crawler çözümü sayfamızda.
- Konum bazlı arama sonucu takibi: Önce resmi API, ardından şehir bazlı çıkış noktaları. Ayrıntılar SEO Sıra Takibi yazımızda.
- Seçicilerin sağlamlığı: Engellenmeseniz de sayfa yapısı değiştiğinde veri boş gelir. Kırılmayan seçici yazmayı CSS Selector ve XPath yazımızda anlattık.
Sık yapılan hatalar
Promise.allveyaasyncio.gatherile yüzlerce isteği birden başlatmak. Toplam hız yüksek görünür ama site başına düşen yük kabul edilemez hâle gelir.429yanıtında hemen yeniden denemek. Geri çekilme olmadan yapılan tekrarlar hız sınırını uzatır.- Kütüphanenin varsayılan
User-Agentdeğerini kullanmak. Birçok site bu değeri doğrudan engeller. - Her istekte rastgele
User-Agentüretmek. Aynı IP ve çerezle değişen kimlik, tutarsızlık sinyalidir. - Oturum gereken işte her istekte IP değiştirmek. Oturum kapanır, giriş sayfasına yönlendirilirsiniz.
- Başarılı durum kodunu başarılı veri sanmak.
200ile gelen doğrulama sayfası, seçiciler boş döndüğü için sessizce bozuk veri üretir. Yanıt içeriğinde beklenen bir öğenin varlığını kontrol edin. - robots.txt'yi okumamak. Sitenin tercihini bilmeden tarama yapmak hem etik hem hukuki açıdan zayıf bir başlangıçtır.
Karar rehberi
| Durumunuz | Öneri |
|---|---|
| Resmi API var | Önce API |
| Tek siteden az sayıda sayfa | Tek IP, düşük hız, tutarlı header |
| Çok sayıda siteden herkese açık sayfa | Site başına düşük eşzamanlılık + rotating proxy |
| Farklı ülke veya şehirdeki içerik | Konum seçimli residential proxy |
| Giriş yapılan kendi hesabınız | Sticky veya sabit IP, oturum boyunca aynı adres |
429 alıyorsunuz | Retry-After kadar bekleyin, eşzamanlılığı düşürün |
| Doğrulama ekranı çıkıyor | Durun, teşhis listesini uygulayın, alternatif arayın |
| Sayfa boş dönüyor | Önce dinamik yükleme olup olmadığını kontrol edin |
| Yol robots.txt'de kapalı | Taramayın |
Sık sorulan sorular
Proxy kullanmak engellenmeyi tamamen önler mi?
Hayır. Proxy trafiği farklı IP adreslerine dağıtır ve konum bazlı içeriği görmenizi sağlar, ama çok hızlı gönderilen, tutarsız header taşıyan ya da sitenin kapattığı yollara giden istekler hangi IP'den gelirse gelsin engellenir. Proxy, doğru hız ve tutarlı istemciyle birlikte işe yarar.
Saniyede kaç istek güvenlidir?
Her site için tek bir güvenli değer yoktur; sitenin altyapısına, sayfanın ağırlığına ve günün saatine bağlıdır. robots.txt'de Crawl-delay belirtilmişse ona uyun. Belirtilmemişse düşük bir hızla başlayın, 429 ve yanıt sürelerini izleyerek yavaşça artırın ve sunucunun yavaşladığını gördüğünüz anda geri çekin.
User-Agent olarak tarayıcı değeri mi, bot adı mı yazmalıyım?
Meşru bir tarayıcı için önerilen yol, botunuzun adını ve bir iletişim adresini yazmaktır. Site yöneticisi kim olduğunuzu görür ve sorun olduğunda size ulaşabilir. Bazı siteler tanımadıkları botları varsayılan olarak engeller; bu durumda izin istemek veya resmi API aramak, tarayıcı gibi görünmeye çalışmaktan daha sağlam bir yoldur.
Headless tarayıcı kullanmak engellenme riskini azaltır mı?
JavaScript ile yüklenen sayfalarda veriyi görmenizi sağlar, ama engellenme riskini kendiliğinden azaltmaz. Aksine her sayfada onlarca ek istek (görsel, betik, stil dosyası) üretir ve siteye daha çok yük bindirir. Önce sayfanın arka planda çağırdığı API isteğini bulmak genellikle daha verimlidir.
IP adresim engellendi, ne kadar sürer?
Siteye göre değişir: birkaç dakikalık hız sınırından günlerce süren kara listeye kadar. Retry-After başlığı varsa süreyi o söyler. Yoksa bir süre bekleyip çok düşük hızla tek bir istek göndererek durumu kontrol edin; engel kalkmadan aynı hızda devam etmeyin.
Tek seferlik küçük bir iş için bu kadar önlem gerekli mi?
Birkaç düzine sayfalık tek seferlik bir iş için istekler arasına birkaç saniye bekleme koymak, anlamlı bir User-Agent kullanmak ve robots.txt'ye bakmak çoğu zaman yeterlidir. Diğer önlemler, iş düzenli ve büyük ölçekli hâle geldiğinde önem kazanır.
Özetle
Scraper'ların çoğu gizlenemedikleri için değil, siteyi yordukları ve tutarsız göründükleri için engellenir. İstek hızını site başına sınırlayın, 429 ve Retry-After yanıtlarına uyun, değişmeyen sayfaları tekrar indirmeyin, kendinizi tanıtan tutarlı bir istemci kimliği kullanın ve robots.txt ile site şartlarını okuyun. IP rotasyonu yükü dağıtmak ve konum bazlı içeriği görmek için, sticky IP ise oturum gerektiren işler içindir; açık bir engeli aşmanın aracı değildir. Veri toplama işleriniz için uygun proxy türlerini proxy hizmetlerimizde bulabilirsiniz.




