Rehber · Güncelleme 2026-10-19

Scrapy ve Playwright’te Rotating Proxy Ayarı

Scrapy ve Playwright proxy ayarı adım adım: request.meta, HttpProxyMiddleware, launch ve context proxy’si, scrapy-playwright birleşimi, 407 ve tünel hataları.

Scrapy ve Playwright’te Rotating Proxy Ayarı

Scrapy ve Playwright proxy ayarı neden iki ayrı katmanda yapılır?

Scrapy ve Playwright proxy ayarı iki farklı yerde yaşar: Scrapy’de proxy her isteğin meta sözlüğüne ya da bir downloader middleware’ine yazılır, Playwright’ta ise tarayıcı başlatılırken veya tarayıcı bağlamı (context) açılırken verilir. Scrapy HTTP istemcisidir ve isteği kendisi kurar; Playwright gerçek bir Chromium, Firefox veya WebKit süreci çalıştırır ve proxy ayarını o sürece devreder. Bu yüzden aynı rotating proxy hesabı iki araçta farklı biçimde, farklı yerlerde tanımlanır ve hata mesajları da farklı görünür.

Rehberdeki örnekler RotatingProxy kataloğundaki ürünlerle çalışır; ürünlerin hepsi HTTP, HTTPS ve SOCKS5 kabul eder. Panelden alınan host, port, kullanıcı adı ve şifre dört parça olarak tutulur; Scrapy bunları tek URL’de ister, Playwright ise server, username ve password alanlarına ayrı ayrı ister. Kimlik bilgisi her iki araçta da ortam değişkeninden okunmalıdır: PROXY_HOST, PROXY_PORT, PROXY_USER ve PROXY_PASS adlı dört değişken, iki aracın da ihtiyacını karşılar.

Scrapy’de proxy: request.meta, ortam değişkeni ve HttpProxyMiddleware

Scrapy’de en kısa yol, isteğe proxy anahtarını eklemektir: yield scrapy.Request(url, meta={"proxy": "http://kullanici:sifre@host:port"}). Scrapy’nin varsayılan olarak açık gelen HttpProxyMiddleware’i bu anahtarı okur, URL’deki kullanıcı adı ve şifreyi ayırıp Proxy-Authorization başlığına çevirir ve isteği proxy üzerinden gönderir. Ek kurulum gerekmez.

Bütün isteklerin proxy’den çıkması istenirse iki seçenek vardır. Birincisi http_proxy ve https_proxy ortam değişkenleridir; HttpProxyMiddleware bu değişkenleri de okur ve meta içinde proxy verilmeyen her istek için kullanır. İkincisi kendi middleware’inizdir: process_request içinde request.meta["proxy"] değerini ortam değişkenlerinden kurduğunuz URL ile doldurursunuz. Kendi middleware’iniz proxy URL’sini tek yerde kurduğu için şifre değişince yalnız bir satır değişir; settings.py içinde DOWNLOADER_MIDDLEWARES sözlüğüne 750’den küçük bir öncelikle eklenir ki HttpProxyMiddleware’den önce çalışsın.

Gateway tabanlı bir rotating proxy’de IP seçimini gateway yaptığı için Scrapy tarafında proxy listesi tutmaya ve isteklere sırayla farklı proxy dağıtmaya gerek yoktur. Tek URL her isteğe yazılır, çıkış IP’sini her istekte gateway değiştirir. Eski rehberlerde görülen rastgele proxy seçen middleware kalıbı, sabit IP listesi olan kurulumlar içindir; gateway’de bu kalıp yalnız gereksiz karmaşıklık ekler.

Şifrede @, : veya / gibi karakterler varsa URL’ye yazmadan önce urllib.parse.quote ile kaçırın. Scrapy URL’yi ayrıştırırken kaçırılmamış bir @ işaretini host ayracı sanır; sonuç, 407 yerine bazen anlaşılmaz bir DNS hatası olur ve kaynağı bulmak uzun sürer.

Scrapy’de hız, yeniden deneme ve oturum: settings.py’de değişecek beş satır

CONCURRENT_REQUESTS ve CONCURRENT_REQUESTS_PER_DOMAIN eşzamanlı istek sayısını belirler. Proxy üzerinden giden isteklerde bağlantı kurma süresi doğrudan erişime göre uzar; 16 ve alan adı başına 8 olan varsayılanları korumak çoğu işte sorun çıkarmaz, ama hedef site 429 döndürmeye başladıysa önce alan adı başına eşzamanlılığı düşürün; daha fazla IP aynı tempoda aynı sınıra takılır.

AUTOTHROTTLE_ENABLED = True ayarı Scrapy’nin hedefin yanıt süresine göre gecikmeyi kendisinin ayarlamasını sağlar. Rotating proxy ile birlikte kullanıldığında yanıt süresi proxy gecikmesini de içerdiği için AUTOTHROTTLE_TARGET_CONCURRENCY değerini düşük tutun; aksi halde Scrapy proxy gecikmesini hedefin yavaşlığı sanıp hızı gereksiz kısar.

RETRY_HTTP_CODES varsayılan listesinde 500, 502, 503, 504, 522, 524, 408 ve 429 bulunur. 429 için yeniden deneme, aynı hızda aynı isteği tekrar göndermek anlamına gelir ve sınırı aşan davranışı sürdürür. Bu kodu listeden çıkarıp kendi middleware’inizde Retry-After başlığını okuyarak bekleyen bir mantık kurmak daha doğru sonuç verir. RETRY_TIMES değerini 2 ile 3 arasında tutun; her deneme GB paketlerde kotadan düşer.

Giriş, filtre, sayfalama gibi birbirine bağlı adımları aynı çıkış IP’sinde tutmak gerekiyorsa iki şey birlikte yapılır. Scrapy tarafında meta içine cookiejar anahtarı verilerek her iş için ayrı çerez kavanozu açılır; proxy tarafında ise IPv4 residential ve mobile ürünlerdeki sticky oturum özelliği kullanılır ve oturum kimliği panelde tanımlanan sözdizimiyle kullanıcı adına eklenir. Oturumlu ve oturumsuz istekleri iki farklı proxy URL’siyle, iki farklı meta kalıbıyla gönderin; aynı örümcekte karışık kullanmak hangi isteğin hangi IP’den çıktığını izlenemez hale getirir.

Playwright’ta proxy: tarayıcıyı başlatırken mi, bağlam açarken mi?

Playwright’ta proxy, tarayıcı başlatılırken verildiğinde o tarayıcıdaki bütün sayfalar aynı proxy’den çıkar: browser = p.chromium.launch(proxy={"server": "http://host:port", "username": kullanici, "password": sifre}). Kimlik bilgisi ayrı alanlara yazılır; Playwright, proxy 407 döndürdüğünde bu alanlarla kimlik doğrulamayı kendisi tamamlar.

Bağlam başına proxy, aynı tarayıcı sürecinde farklı işlerin farklı proxy ayarıyla çalışmasını sağlar: context = browser.new_context(proxy={...}). Her bağlam kendi çerezlerini, depolama alanını ve proxy ayarını taşır. Chromium’da bağlam başına proxy kullanırken tarayıcıyı başlatırken de bir proxy belirtmek gerekebilir; Playwright belgeleri bunun için launch çağrısına per-context yer tutucusunu vermeyi anlatır. Firefox ve WebKit’te bu ek adım yoktur.

Chromium tabanlı Playwright, kullanıcı adı ve şifre isteyen SOCKS5 proxy’lerle çalışmaz; SOCKS5 yalnız kimlik doğrulaması istemeyen, IP whitelist ile açılan kurulumlarda kullanılabilir. Rotating proxy hesabınız kullanıcı adı ve şifreyle doğrulanıyorsa Playwright tarafında HTTP uç noktasını seçin. Scrapy tarafında ise SOCKS5 için scrapy’nin kendisi destek vermez; Playwright’ı da HTTP ile kurmak iki aracı aynı ayarla çalıştırır.

bypass alanı, proxy’den geçmemesi gereken adresleri virgülle ayrılmış liste olarak alır: proxy={"server": ..., "bypass": "localhost,127.0.0.1,*.sirketici.local"}. Kendi test sunucunuz, yerel ağdaki bir API ya da proxy’den geçmesi anlamsız olan statik varlık sunucuları buraya yazılır. Bu liste boş bırakılırsa yerel adrese giden istekler de proxy üzerinden dolaşır ve proxy tarafında anlamsız bağlantı hataları üretir.

Playwright’ta rotasyon ve kota: bağlam yönetimi

Gateway her yeni TCP bağlantısında IP değiştirebilir, ama bir tarayıcı bağlamı açık kaldığı sürece bağlantılarını yeniden kullanır; aynı bağlamda art arda açılan sayfalar sık sık aynı çıkış IP’sinde kalır. Her iş için farklı IP istiyorsanız her iş için yeni bağlam açıp kapatın. Çok adımlı akış için ise tek bağlam ve sticky oturum kimlikli proxy kullanıcı adı doğru seçimdir; bağlam açıkken IP sabit kalır, kapanınca oturum da biter.

Tarayıcı, Scrapy’ye göre kat kat fazla veri çeker: sayfa HTML’i yanında görseller, yazı tipleri, reklam betikleri ve izleme çağrıları da proxy’den geçer ve GB bazlı paketlerde kotadan düşer. context.route ile görsel, yazı tipi ve medya isteklerini durdurmak (route.abort()) veri tüketimini düşürmenin ilk adımıdır. İhtiyaç duyulmayan üçüncü taraf alan adlarını da aynı yöntemle kesin.

Kaç bağlamın aynı anda açık kalacağını sabit bir sayıyla sınırlayın; sayfa başına bellek tüketimi yüksektir ve sınırsız bağlam sayısı önce makinenin belleğini, sonra proxy tarafındaki eşzamanlı bağlantı sayısını zorlar. Her bağlamın ömrünü de sınırlayın: bir iş bitince context.close() çağrısı hem belleği hem de oturumu serbest bırakır.

scrapy-playwright ile ikisini aynı örümcekte kullanmak

scrapy-playwright eklentisi, Scrapy örümceğinin istediği sayfaları Playwright ile açıp sonucu Scrapy’ye geri verir. Kurulumdan sonra settings.py içinde DOWNLOAD_HANDLERS sözlüğü http ve https için scrapy_playwright.handler.ScrapyPlaywrightDownloadHandler değerini alır, TWISTED_REACTOR ise AsyncioSelectorReactor olur. Hangi isteğin tarayıcıyla açılacağını meta={"playwright": True} belirler; diğer istekler Scrapy’nin kendi istemcisiyle gider.

Proxy bu kurulumda üç yerden verilebilir. PLAYWRIGHT_LAUNCH_OPTIONS = {"proxy": {"server": ..., "username": ..., "password": ...}} bütün tarayıcı sayfalarına uygulanır. PLAYWRIGHT_CONTEXTS sözlüğüyle adlandırılmış bağlamlar tanımlanır ve her bağlama kendi proxy’si verilir; istek meta’sındaki playwright_context anahtarı isteğin hangi bağlamda açılacağını söyler. Üçüncü yol, isteğin meta’sında playwright_context_kwargs ile yeni bağlam için proxy vermektir. Scrapy’nin kendi istemcisiyle giden istekler ise yine meta içindeki proxy anahtarını kullanır; bu anahtar tarayıcı isteklerini etkilemez.

Liste ve kategori sayfaları gibi düz HTML dönen adresler Scrapy istemcisiyle, JavaScript ile dolan ürün detayı ve sonsuz kaydırmalı sayfalar Playwright ile alınır. Her iki taraf da aynı gateway’i kullandığı için kota tek paketten düşer; Playwright isteklerinin payı deneme taramasında ölçülüp bütçe ona göre ayrılmalıdır.

Hata, neden, çözüm: 407, tünel hatası, 429 ve donan sayfa

407 Proxy Authentication Required (Scrapy): Kullanıcı adı veya şifre URL’de yanlış ya da kaçırılmamış özel karakter var. Kendi middleware’iniz HttpProxyMiddleware’den sonra çalışıyorsa Proxy-Authorization başlığı üretilmez; öncelik sayısını 750’nin altına çekin. IP whitelist modundaysanız örümceğin çalıştığı sunucunun IP’sinin panelde tanımlı olduğunu kontrol edin.

net::ERR_PROXY_CONNECTION_FAILED veya ERR_TUNNEL_CONNECTION_FAILED (Playwright): Tarayıcı proxy’ye ulaşamadı ya da proxy hedefe tünel açamadı. İlkinde host, port ve giden port izinlerini; ikincisinde hedefin HTTPS portuna erişimi ve proxy’nin o hedefe çıkabildiğini kontrol edin. Kimlik bilgisini server alanındaki URL’ye gömdüyseniz çıkarıp username ve password alanlarına taşıyın.

Playwright’ta kimlik doğrulama penceresi açılması: proxy ayarında username ve password eksik kaldığında Chromium 407 yanıtını kullanıcıya sorar ve betik bekler. İki alanı launch ya da new_context çağrısına ekleyin.

429 Too Many Requests (her ikisi): Hatayı hedef site döndürür. Scrapy’de alan adı başına eşzamanlılığı düşürüp Retry-After kadar bekleyin; Playwright’ta bağlam sayısını azaltın ve aynı bağlamda sayfalar arasında gerçekçi bekleme bırakın. IP değişse de aynı başlık seti ve aynı tempo sürerse sınır yeniden tetiklenir.

Donan sayfa ve zaman aşımı (Playwright): page.goto varsayılan olarak load olayını bekler; proxy üzerinden yüklenen reklam ve izleme betikleri bu olayı uzatır. wait_until="domcontentloaded" ile daha erken dönüp gereken öğeyi page.wait_for_selector ile bekleyin, gereksiz kaynakları route ile kesin. Zaman aşımını hedefin tipik yükleme süresine göre açıkça verin.

Hangi IP’den çıkıldığını doğrulamak için iki araçtan da istemci IP’sini düz metin döndüren bir uç noktaya istek atın. Scrapy’de üç ardışık istek, Playwright’ta üç ayrı bağlam ve üç ayrı sayfa açıp sonuçları karşılaştırmak, rotasyon davranışını birkaç dakikada doğrular.

Hangi aracı hangi işte kullanmalı?

Hedef sayfa sunucudan hazır HTML dönüyorsa Scrapy tek başına yeterlidir: daha az bellek, daha az veri, daha yüksek istek hızı. Fiyat listeleri, kategori sayfaları, site haritasından toplanan adresler ve arama sonuçlarının büyük bölümü bu sınıfa girer.

İçerik yalnız JavaScript çalışınca oluşuyorsa, sayfa kaydırdıkça yükleniyorsa ya da bir etkileşim (filtre seçimi, sekme) sonrası görünüyorsa Playwright gerekir. Uygulama ve geo QA testleri de bu sınıftadır; farklı ülkelerden açılan gerçek tarayıcı görünümünü yalnız tarayıcı verir.

İkisinin karışık olduğu sitelerde scrapy-playwright ile tek örümcek kurulur, tarayıcı yalnız gereken sayfalara açılır. Bu düzen kota ve bellek açısından en ekonomik seçenektir, ama iki aracın proxy ayarlarının ayrı yerlerde durduğunu unutmamak gerekir: Scrapy istekleri meta içindeki proxy anahtarıyla, tarayıcı istekleri PLAYWRIGHT_LAUNCH_OPTIONS ya da bağlam ayarıyla çıkar. Birini ayarlayıp diğerini unutmak, isteklerin bir bölümünün kendi IP’nizden çıkmasına yol açar; canlıya almadan önce iki yoldan da IP kontrolü yapın.

İlgili ürünler

İç bağlantılar