Bir HTTP proxy sunucusu, web scraping scriptiniz ile hedef web sitesi arasında aracı olarak çalışır. Scrapy spider'ınız hedefe doğrudan bağlanmak yerine proxy sunucusuna bağlanır; proxy de isteği hedefe iletir. Bu sayede IP adresinizi gizleyebilir, coğrafi kısıtlamaları aşabilir ve anti-scraping önlemleri kullanan sitelerde bloklanmaktan kaçınabilirsiniz. Bu makale, Scrapy middleware kullanarak proxy kurmak ve rotasyon yapmak için pratik bir rehber sunar.
Scrapy'de middleware ile proxy kurulumu
Scrapy'nin middleware sistemi, istekleri ve yanıtları işlemek için esnek bir yol sunar. Proxy desteğini uygulamak için bu sistemden yararlanabiliriz. Süreç, istekleri yakalayan ve onlara bir proxy sunucusu atayan özel bir middleware oluşturmayı içerir.
Özel bir proxy middleware oluşturma
Öncelikle Scrapy projenizde yeni bir Python dosyası (örneğin proxy_middleware.py) oluşturun. Bu dosya, özel proxy middleware'inizin kodunu içerecek.
import random
class ProxyMiddleware:
def __init__(self, proxies):
self.proxies = proxies
@classmethod
def from_crawler(cls, crawler):
return cls(crawler.settings.getlist('PROXIES'))
def process_request(self, request, spider):
proxy = random.choice(self.proxies)
request.meta['proxy'] = proxy
print(f"Using proxy: {proxy}")
def process_response(self, request, response, spider):
# İsteğe bağlı: farklı bir proxy ile yeniden denemek için yanıt kodlarını işleyin
if response.status in [403, 429]:
print(f"Proxy {request.meta['proxy']} blocked, retrying with another proxy.")
return self._retry_request(request, spider)
return response
def _retry_request(self, request, spider):
proxy = random.choice(self.proxies)
request.meta['proxy'] = proxy
new_request = request.copy()
return new_request
Açıklama:
__init__(self, proxies): Yapıcı metot, girdi olarak bir proxy listesi alır.from_crawler(cls, crawler): Bu sınıf metodu, Scrapy tarafından middleware'in bir örneğini oluşturmak için kullanılır. Proxy listesini Scrapy ayarlarından alır.process_request(self, request, spider): Bu metot, Scrapy bir istek göndermeden önce çağrılır. Listeden rastgele bir proxy seçer ve isteğinmeta['proxy']özniteliğine atar. Böylece Scrapy'ye bu istek için belirtilen proxy'yi kullanmasını söyler.process_response(self, request, response, spider): Bu metot, sunucudan gelen yanıtı işlemenizi sağlar. Burada, proxy'nin bloklandığını gösteren 403 (Forbidden) veya 429 (Too Many Requests) gibi durum kodları kontrol edilir. Bir bloklama kodu bulunursa istek farklı bir proxy ile yeniden denenir._retry_request(self, request, spider): Bu metot, farklı bir proxy atanmış yeni bir istek oluşturur.
Scrapy ayarlarını yapılandırma
Ardından, middleware'i etkinleştirmek ve bir proxy listesi sağlamak için Scrapy ayarlarınızı yapılandırmanız gerekir. settings.py dosyanızı açın ve aşağıdakileri ekleyin:
# settings.py
# ProxyMiddleware'i etkinleştir
DOWNLOADER_MIDDLEWARES = {
'your_project_name.proxy_middleware.ProxyMiddleware': 350, # Önceliği gerektiği gibi ayarlayın
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': None, # Varsayılan HttpProxyMiddleware'i devre dışı bırak
}
# Proxy listesi
PROXIES = [
'http://user1:[email protected]:8080',
'http://user2:[email protected]:8080',
'http://user3:[email protected]:8080',
'https://user4:[email protected]:8080',
]
# Proxy'ler sık başarısız olduğundan çok sayıda yeniden deneme yapın
RETRY_TIMES = 10
# Proxy'ler sık başarısız olduğundan çoğu hata kodunda yeniden deneyin
RETRY_HTTP_CODES = [500, 502, 503, 504, 400, 408]
# Varsayılan user agent middleware'ini devre dışı bırakıp özel bir tane kullan
DOWNLOADER_MIDDLEWARES.update({
'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
'scrapy_user_agents.middlewares.RandomUserAgentMiddleware': 400,
})
# robots.txt kurallarına uy
ROBOTSTXT_OBEY = False
Açıklama:
DOWNLOADER_MIDDLEWARES: Bu sözlük, downloader middleware'lerini etkinleştirir ve yapılandırır. Anahtar, middleware sınıfınızın yolu; değer ise middleware'in önceliğidir. Daha küçük sayılar daha yüksek önceliği gösterir (middleware daha erken çalışır). Özel middleware ile çakışmayı önlemek için varsayılanHttpProxyMiddlewaredevre dışı bırakılır.PROXIES: Bu liste, kullanmak istediğiniz proxy sunucularını içerir. Biçim şöyledir:protocol://user:password@host:port. Hem HTTP hem de HTTPS proxy'ler kullanılabilir. Kullanıcı adı ve parola gerekmiyorsa biçim yalnızcaprotocol://host:portolur.RETRY_TIMESveRETRY_HTTP_CODES: Bu ayarlar Scrapy'nin retry middleware'ini yapılandırır. Proxy'ler güvenilmez olabildiğinden, deneme sayısını artırmak ve proxy sorununa işaret edebilecek yaygın HTTP hata kodlarını eklemek iyi bir uygulamadır.DOWNLOADER_MIDDLEWARES.update(...): Bu bölüm, varsayılan User Agent middleware'ini devre dışı bırakır ve User Agent rotasyonu içinscrapy_user_agentspaketini etkinleştirir. Bu, scraper'ınızın kolayca tespit edilmesini önlemeye yardımcı olur.scrapy_user_agentspaketinipip install scrapy-user-agentsile kurmanız gerekir.
Spider'ı çalıştırma
Artık Scrapy spider'ınızı her zamanki gibi çalıştırabilirsiniz. Middleware her isteğe otomatik olarak bir proxy atayacaktır.
scrapy crawl your_spider_name
Proxy rotasyon stratejileri
Scraper'ınızın bloklanmasını önlemek için proxy rotasyonu kritik önemdedir. Yaygın stratejiler şunlardır:
- Rastgele seçim: Yukarıdaki örnekte uygulandığı gibi, her istek için listeden rastgele bir proxy seçmek. En basit yaklaşımdır ama en etkilisi olmayabilir.
- Sıralı rotasyon: Proxy listesinde sırayla ilerlemek. Her proxy'nin eşit sayıda kullanıldığından emin olmak istiyorsanız yararlıdır.
- Akıllı rotasyon: Her proxy'nin performansını izleyen ve iyi çalışanlara öncelik veren bir mantık kurmak. Bu, yanıt sürelerini, hata oranlarını ve diğer metrikleri izlemeyi içerebilir.
- Proxy API kullanımı: Proxy rotasyonunu ve yönetimini otomatik olarak halleden bir proxy servisi API'sinden yararlanmak. Bu servisler genellikle geo-targeting ve IP adresi itibar yönetimi gibi özellikler sunar.
Sıralı proxy rotasyonu
Middleware'inizde sıralı proxy rotasyonunu uygulamaya dair bir örnek:
import itertools
class SequentialProxyMiddleware:
def __init__(self, proxies):
self.proxies = itertools.cycle(proxies) # Proxy'leri döndürmek için cycle kullan
@classmethod
def from_crawler(cls, crawler):
return cls(crawler.settings.getlist('PROXIES'))
def process_request(self, request, spider):
proxy = next(self.proxies) # Döngüden bir sonraki proxy'yi al
request.meta['proxy'] = proxy
print(f"Using proxy: {proxy}")
def process_response(self, request, response, spider):
if response.status in [403, 429]:
print(f"Proxy {request.meta['proxy']} blocked, rotating to the next proxy.")
return self._retry_request(request, spider)
return response
def _retry_request(self, request, spider):
proxy = next(self.proxies)
request.meta['proxy'] = proxy
new_request = request.copy()
return new_request
Temel değişiklik:
itertools.cycle(proxies): Bu, proxy listesinde sonsuz döngüyle ilerleyen bir yineleyici oluşturur. Sıradaki proxy'yi almak içinnext()fonksiyonu kullanılır.
DOWNLOADER_MIDDLEWARES ayarınızı SequentialProxyMiddleware'i gösterecek şekilde güncellemeyi unutmayın.
Proxy API entegrasyonu
Bir proxy API'siyle entegrasyon genellikle proxy almak için API'ye istek göndermeyi, ayrıca API'nin kimlik doğrulamasını ve hata yanıtlarını işlemeyi içerir. Ayrıntılar seçtiğiniz API'ye bağlıdır. Birçok proxy sağlayıcısı bu süreci kolaylaştırmak için Python SDK'ları sunar.
Proxy türleri
Farklı proxy türlerinin karşılaştırması:
| Özellik | HTTP proxy | HTTPS proxy | SOCKS proxy |
|---|---|---|---|
| Protokol | HTTP | HTTPS | SOCKS (çeşitli sürümler) |
| Şifreleme | İstemci ile proxy arasında şifreleme yok | İstemci ile proxy arasında şifreleme var | Şifreleme SOCKS sürümüne bağlıdır |
| Kullanım alanları | Web'de gezinme, HTTP sitelerini scraping | Web'de gezinme, HTTPS sitelerini scraping | Genel amaçlı, çeşitli protokolleri destekler |
| Anonimlik | Daha az anonim olabilir | Daha anonim olabilir | Çok yüksek anonimlik sağlayabilir |
| Yapılandırma | Genellikle tarayıcılarda yapılandırılır | Genellikle tarayıcılarda yapılandırılır | SOCKS istemcisi veya kütüphane desteği ister |
| Örnek URL | http://host:port |
https://host:port |
socks5://host:port veya socks4://host:port |
| Kimlik doğrulama | Basic authentication (kullanıcı adı/parola) | Basic authentication (kullanıcı adı/parola) | Kullanıcı adı/parola doğrulaması desteklenir |
Sık karşılaşılan sorunlar ve çözümleri
- Proxy'ler çalışmıyor: Proxy sunucusunun çevrimiçi ve erişilebilir olduğunu doğrulayın. Proxy'nin kimlik bilgilerini (kullanıcı adı ve parola) kontrol edin.
settings.pyiçindeki proxy biçiminin doğru olduğundan emin olun. - Bloklanmış proxy'ler: Proxy rotasyonu uygulayın ve geniş bir IP adres havuzuna sahip bir proxy servisi kullanmayı değerlendirin. Yanıt kodlarını (403, 429) izleyin ve istekleri otomatik olarak farklı proxy'lerle yeniden deneyin.
- Yavaş performans: Hedef sunucuya coğrafi olarak yakın proxy'ler seçin. Güvenilir performans veren birini bulmak için farklı proxy sağlayıcılarını test edin.
- HTTPS hataları: Proxy'nizin HTTPS bağlantılarını desteklediğinden emin olun. Bazı HTTP proxy'ler yalnızca HTTP trafiğini destekler.
- DNS sızıntıları: DNS sızıntılarını önlemek için bir SOCKS proxy kullanın ya da sisteminizi proxy'nin DNS sunucusunu kullanacak şekilde yapılandırın.
Sonuç
Scrapy'de proxy kurmak ve rotasyon yapmak, sağlam ve güvenilir web scraper'lar oluşturmak için şarttır. Özel middleware kullanarak, etkili rotasyon stratejileri uygulayarak ve farklı proxy türlerini anlayarak bloklanma riskini önemli ölçüde azaltabilir, scraping projelerinizin performansını artırabilirsiniz. Optimal scraping verimliliğini korumak için proxy'lerinizi sürekli izlemeyi ve stratejinizi gerektiği gibi uyarlamayı unutmayın.
Proxy'lerinizi düzenli olarak test etmeyi ve performanslarını izlemeyi unutmayın; böylece scraper'ınız etkin şekilde çalışmaya devam eder. Daha gelişmiş özellikler ve daha kolay yönetim için bir proxy yönetim servisi kullanmayı değerlendirin.
