Python'da web scraping yapan birçok geliştirici, requests kütüphanesi ile Selenium/Playwright arasında sürekli geçiş yapmak zorunda kalır. HTTP istekleri hızlı ve ucuzdur ama JavaScript ile render edilen sayfaları açamaz; headless tarayıcılar her şeyi çözer ama her sayfa için 200-500 MB RAM tüketir ve saniyede onlarca istek yerine birkaç istek yapabilir. DrissionPage, bu iki dünyayı tek bir API altında birleştiren bir Python framework'üdür ve doğru proxy yapılandırmasıyla üretim ölçeğinde kullanılabilir.
Bu rehberde DrissionPage'in SessionPage (HTTP), ChromiumPage (CDP tabanlı tarayıcı) ve WebPage (modlar arası geçiş) modellerini inceleyecek, ProxyHat residential proxy'lerini framework'ün idiomatik API'sine nasıl entegre edeceğinizi göstereceğiz. Önemli uyarı: yalnızca herkese açık verileri toplayın, hedef sitenin robots.txt dosyasına ve kullanım şartlarına uyun. CFAA ve GDPR kapsamında yetkisiz erişim veya kişisel verilerin izinsiz işlenmesi ciddi hukuki sonuçlar doğurabilir; resmi API varsa onu tercih edin.
DrissionPage Nedir ve Proxy Kullanıcıları İçin Neden Önemli?
DrissionPage, Çinli geliştirici g1879 tarafından açık kaynak olarak geliştirilen ve GitHub üzerinde 25.000+ yıldıza ulaşan bir Python framework'üdür. Temel farkı, aynı oturum (session) içinde HTTP modu ile tarayıcı modu arasında durum paylaşımı yaparak geçiş yapabilmesidir: çerezler, headers ve localStorage verileri mod değiştirildiğinde korunur.
Proxy kullanıcıları için bu kritik bir avantajdır. Çünkü:
- Maliyet optimizasyonu: Basit HTML sayfaları için tarayıcı açmak yerine SessionPage ile saniyede 1500+ istek atabilirsiniz; yalnızca JS-render gereken sayfalarda ChromiumPage'e geçersiniz.
- IP rotasyonu: Her mod için farklı proxy stratejileri uygulayabilirsiniz — HTTP modunda per-request rotasyon, tarayıcı modunda sticky session.
- Paket yakalama:
listen.start()ile arka plan XHR/JSON isteklerini yakalayabilir, gizli API'leri keşfedebilirsiniz.
DrissionPage Mimarisi: Üç Sayfa Sınıfı
DrissionPage'in çekirdeği üç sayfa sınıfından oluşur. Her birinin farklı bir maliyet ve performans profili vardır:
| Özellik | SessionPage | ChromiumPage | WebPage |
|---|---|---|---|
| Alt tabaka | requests / urllib3 | Chromium CDP | İkisi birden |
| Hız (istek/sn) | 1500+ (proxy bağımlı) | 5-15 | Moduna göre değişir |
| RAM kullanımı | ~20 MB | 200-500 MB | 200-500 MB |
| JS render | Hayır | Evet | Evet (mod geçişinde) |
| Durum paylaşımı | Tek oturum | Tek tarayıcı | Oturum ↔ Tarayıcı |
SessionPage: Hızlı HTTP Modu
SessionPage, requests.Session üzerine inşa edilmiştir. Proxy desteği set_proxies() metodu ile yerleşiktir:
from DrissionPage import SessionPage
page = SessionPage()
page.set.proxies({
'http': 'http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080',
'https': 'http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080'
})
page.get('https://example.com')
print(page.html[:500])
Bu mod, statik HTML sayfalarında tarayıcıya göre 100 kata kadar daha hızlıdır ve RAM tüketimi ~20 MB seviyesindedir. ProxyHat residential endpoint'i üzerinden ABD merkezli bir IP ile istek atarsınız; session-abc123 flag'i aynı IP'yi korur.
ChromiumPage: CDP Tabanlı Tarayıcı Kontrolü
ChromiumPage, Chrome DevTools Protocol (CDP) üzerinden tarayıcıyı kontrol eder. Selenium'dan farklı olarak WebDriver protokolü kullanmaz; bu da daha düşük gecikme ve daha az tespit edilebilirlik sağlar. Proxy yapılandırması ChromiumOptions üzerinden yapılır:
from DrissionPage import ChromiumPage, ChromiumOptions
co = ChromiumOptions()
co.set_proxy('http://user-country-DE-city-berlin-session-def456:pass@gate.proxyhat.com:8080')
co.headless(True)
co.set_argument('--no-sandbox')
co.set_argument('--disable-gpu')
page = ChromiumPage(co)
page.get('https://spa-site.example.com')
page.wait.eles_displayed('tag:div@class=product-card')
print(page.eles('tag:div@class=product-card')[0].text)
Buradaki set_proxy() metodu, Chromium'u başlatma aşamasında proxy'yi enjekte eder. --no-sandbox ve --disable-gpu argümanları container ortamlarında çalıştırmak için gereklidir.
WebPage: Modlar Arası Geçiş
WebPage, en güçlü sınıftır. HTTP modunda başlayıp gerektiğinde tarayıcı moduna geçebilir ve geçişte çerezler ile oturum durumu korunur. Bu, maliyeti dramatik şekilde düşürür:
from DrissionPage import WebPage
# HTTP modunda başla — hızlı ve ucuz
page = WebPage()
page.set.proxies({
'http': 'http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080',
'https': 'http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080'
})
page.get('https://shop.example.com/products')
# Sayfa JS-render gerektiriyorsa tarayıcıya geç
if 'product-grid' not in page.html:
page.change_mode() # ChromiumPage'e geç, çerezler korunur
page.get('https://shop.example.com/products')
page.wait.eles_displayed('tag:div@class=product-grid')
products = page.eles('xpath://div[contains(@class,"product-card")]')
for p in products[:5]:
print(p.ele('tag:h2').text, p.ele('tag:span@class=price').text)
Bu örnekte change_mode() çağrıldığında, SessionPage'in tuttuğu çerezler otomatik olarak Chromium tarayıcısına aktarılır. ProxyHat'ın session-abc123 flag'i sayesinde aynı residential IP her iki modda da kullanılır — tarayıcıya geçtiğinizde IP değişmez ve hedef site oturumu tanımaya devam eder.
DrissionPage Proxy Yapılandırması: Detaylı Kurulum
DrissionPage proxy entegrasyonu iki seviyede gerçekleşir. SessionPage için set.proxies() metodu Python requests kütüphanesinin proxy sözlüğünü kullanır. ChromiumPage için ChromiumOptions.set_proxy() metodu Chromium başlatma argümanlarına proxy'yi enjekte eder.
ProxyHat SDK ile Kullanıcı Adı Oluşturma
ProxyHat'ın geo-targeting ve session flag'leri kullanıcı adı alanına gömülür. Üretimde bu username'leri programatik oluşturmak gerekir:
import random
import string
def build_proxyhat_username(country='US', city=None, session_id=None):
"""ProxyHat residential proxy için kullanıcı adı oluştur."""
parts = [f'country-{country}']
if city:
parts.append(f'city-{city}')
if session_id is None:
session_id = ''.join(random.choices(string.ascii_lowercase + string.digits, k=8))
parts.append(f'session-{session_id}')
return '-'.join(parts)
def build_proxy_url(username, password='pass', socks5=False):
port = 1080 if socks5 else 8080
scheme = 'socks5' if socks5 else 'http'
return f'{scheme}://{username}:{password}@gate.proxyhat.com:{port}'
# Örnek kullanım
user = build_proxyhat_username(country='US', city='newyork', session_id='order-123')
proxy_url = build_proxy_url(user)
print(proxy_url)
# Çıktı: http://user-country-US-city-newyork-session-order-123:pass@gate.proxyhat.com:8080
Bu helper fonksiyon, her scraping görevi için benzersiz session ID'ler üretmenizi sağlar. Aynı session ID kullanan tüm istekler aynı residential IP'den çıkar — bu, oturum açma gerektiren sitelerde (e-ticaret, sosyal medya) kritik önem taşır.
Residential vs Datacenter Proxy Seçimi
DrissionPage ile scraping yaparken proxy tipi seçimi hedef sitenin anti-bot savunmasına bağlıdır:
| Özellik | Residential Proxy | Datacenter Proxy |
|---|---|---|
| IP kaynağı | Gerçek ISP'ler | Veri merkezi blokları |
| Tespit zorluğu | Yüksek | Düşük |
| Hız | Orta (50-200ms) | Yüksek (10-50ms) |
| Fiyat (ProxyHat) | GB başına | IP başına |
| Uygun kullanım | Anti-bot korumalı siteler | Basit HTML scraping |
Cloudflare, DataDome veya PerimeterX korumalı sitelerde datacenter IP'ler genellikle ilk istekte 403 alır. Residential proxy'ler ise gerçek ISP IP'leri olduğu için bu sistemleri geçer. ProxyHat fiyatlandırması sayfasından her iki tip için de güncel fiyatları görebilirsiniz.
listen.start() ile Arka Plan XHR/JSON Yakalama
DrissionPage'in en güçlü özelliklerinden biri listen API'sidir. ChromiumPage'de arka plan isteklerini gerçek zamanlı yakalayabilir, gizli API'leri keşfedebilirsiniz:
from DrissionPage import ChromiumPage, ChromiumOptions
co = ChromiumOptions()
co.set_proxy('http://user-country-US-session-listen01:pass@gate.proxyhat.com:8080')
co.headless(True)
page = ChromiumPage(co)
# API isteklerini dinlemeye başla
page.listen.start('api/products')
page.get('https://shop.example.com/catalog')
# İlk API yanıtını yakala (timeout: 15 saniye)
packet = page.listen.wait(timeout=15)
if packet:
print(f'URL: {packet.url}')
print(f'Status: {packet.response.status}')
data = packet.response.body # JSON dict olarak döner
print(f'Ürün sayısı: {len(data.get("products", []))}')
page.listen.stop()
Bu yöntem, sayfanın DOM'unu parse etmek yerine doğrudan arka plan API'sinden JSON verisini yakalar. Bir e-ticaret sitesinde 500 ürünü DOM üzerinden çekmek 30-60 saniye sürerken, API yakalama ile aynı veri 2-3 saniyede elde edilebilir.
Üretim Desenleri: Ölçeklenebilir Scraping Mimarisi
Per-Session Proxy Pinning
Üretimde her scraping görevi için benzersiz bir session ID atayın. Bu, aynı IP'nin tüm isteklerde korunmasını sağlar ve hedef sitede tutarlı bir oturum görünümü yaratır:
import uuid
from DrissionPage import WebPage
def scrape_with_pinned_session(url, country='US'):
session_id = str(uuid.uuid4())[:8]
username = f'user-country-{country}-session-{session_id}'
proxy_url = f'http://{username}:pass@gate.proxyhat.com:8080'
page = WebPage()
page.set.proxies({'http': proxy_url, 'https': proxy_url})
try:
page.get(url, timeout=20)
if page.status != 200:
raise Exception(f'HTTP {page.status}')
# JS render gerekirse tarayıcıya geç
if page.ele('tag:div@class=app-root', timeout=3):
page.change_mode()
page.get(url)
page.wait.eles_displayed('tag:div@class=content', timeout=15)
return page.html
finally:
page.close()
Retry ve Hata Yönetimi
Proxy tabanlı scraping'de başarısızlık oranını hesaba katın. 1000 istekte 950+ başarılı sonuç iyi bir orandır; 99%+ başarı için residential proxy + retry kombinasyonu gerekir:
import time
from DrissionPage import SessionPage
def fetch_with_retry(url, max_retries=3, country='US'):
for attempt in range(max_retries):
session_id = f'retry-{attempt}-{int(time.time())}'
proxy_url = f'http://user-country-{country}-session-{session_id}:pass@gate.proxyhat.com:8080'
page = SessionPage()
page.set.proxies({'http': proxy_url, 'https': proxy_url})
try:
resp = page.get(url, timeout=15)
if page.status == 200:
return page.html
elif page.status == 429:
time.sleep(5 * (attempt + 1)) # Rate limit — backoff
elif page.status == 403:
continue # IP engellendi, yeni IP dene
except Exception as e:
print(f'Deneme {attempt + 1} başarısız: {e}')
finally:
page.close()
return None
429 (Too Many Requests) durumunda üstel geri çekilme (exponential backoff) uygulayın. 403 durumunda ise yeni bir session ID ile yeni IP alın — ProxyHat'ın residential havuzu bu geçişleri saniyeler içinde yapar.
Eşzamanlılık ve Container Orchestration
DrissionPage'i container'da çalıştırırken şu noktalara dikkat edin:
- ChromiumPage başına ~300 MB RAM ayrın; 16 GB RAM'li bir sunucuda maksimum 40-50 eşzamanlı tarayıcı çalışır.
- SessionPage başına ~20 MB RAM yeterlidir; aynı sunucuda 500+ eşzamanlı HTTP oturumu mümkündür.
- Her container'a benzersiz session ID atamak için container ID'yi kullanın:
session-{hostname}-{task_id}. - Headless modda
--no-sandboxve--disable-dev-shm-usageargümanları zorunludur; aksi halde Docker'da çökebilir.
ProxyHat'ın residential proxy havuzu 195+ ülkede IP sunar. Her container'a farklı bir ülke atayarak coğrafi dağılım sağlayabilir ve hedef sitenin tek bir bölgeden gelen ani trafik artışından şüphelenmesini engelleyebilirsiniz.
Ne Zaman Tarayıcıya Geçmemelisiniz?
DrissionPage'in gücü mod geçişinde olsa da, her durumda tarayıcıya geçmek doğru değildir. İşte tarayıcıya geçmemeniz gereken durumlar:
- Statik HTML: Sayfa sunucu tarafında render ediliyorsa SessionPage yeterlidir. 200ms yanıt süresine karşı tarayıcıda 3-5 saniye.
- API yakalama:
listen.start()ile API'yi yakaladıktan sonra, doğrudan SessionPage ile o API'yi çağırmak daha verimlidir. - Yüksek hacim: 10.000+ sayfa taranacaksa, tarayıcı maliyeti (RAM + süre) HTTP moduna göre 50-100x daha yüksektir.
- Basit form gönderimi: POST istekleri SessionPage ile doğrudan yapılabilir; JS gerektiren form validasyonu yoksa tarayıcı açmayın.
Pratik kural: önce SessionPage dene, page.status 200 ise ve içeriği parse edebiliyorsan tarayıcıya geçme. 200 dönüyor ama içerik boşsa veya JS framework işaretleri varsa (__NEXT_DATA__, window.__APOLLO_STATE__), o zaman change_mode() çağır.
DrissionPage Web Scraping için Etik İlkeler
Scraping yapmadan önce şu adımları izleyin:
- Hedef sitenin
robots.txtdosyasını kontrol edin.User-agent: *altındaDisallow: /private/gibi kurallar varsa bunlara uyun. - Resmi API varsa onu kullanın. Birçok e-ticaret ve sosyal medya platformu API sunar; scraping'den daha hızlı ve yasal olarak daha güvenlidir.
- Rate limit uygulayın. Saniyede 5-10 istek, çoğu site için kabul edilebilir bir hızdır; saniyede 100+ istek DDoS benzeri davranıştır.
- Kişisel verileri toplamayın. GDPR kapsamında kişisel verilerin işlenmesi için açık rıza gerekir; e-posta, telefon, isim gibi verileri izinsiz toplamak yasa dışı olabilir.
- Toplanan verileri ticari amaçla yeniden yayınlamayın. Telif hakkı korunan içerikleri başka bir sitede yayınlamak yasal sorun yaratır.
Daha fazla scraping kullanım senaryosu için web scraping kullanım sayfamızı ve SERP takip rehberimizi inceleyebilirsiniz. Teknik dokümantasyon için ProxyHat dokümantasyonunu ziyaret edin.
Önemli Çıkarımlar
- DrissionPage tek bir framework'te HTTP ve tarayıcı modlarını birleştirir; durum paylaşımı yaparak geçiş sağlar ve maliyeti düşürür.
- SessionPage saniyede 1500+ istek atabilir; ChromiumPage JS-render gerektiren sayfalar için gereklidir ama 200-500 MB RAM tüketir.
- ProxyHat residential proxy'leri
gate.proxyhat.com:8080üzerinden, username'e gömülü flag'lerle (country, city, session) yapılandırılır.listen.start()ile arka plan API'lerini yakalayarak DOM parsing yerine doğrudan JSON verisi elde edebilirsiniz.- Üretimde per-session proxy pinning, retry mekanizması ve eşzamanlılık limitleri uygulayın.
- Etik scraping: robots.txt'ye uyun, resmi API'leri tercih edin, kişisel verileri toplamayın.
DrissionPage ve ProxyHat kombinasyonu, hem hız hem de gizlilik gerektiren scraping projelerinde güçlü bir araç seti sunar. Basit HTML sayfalarında SessionPage ile 100x hız kazanırken, JS-render gereken sayfalarda ChromiumPage'e geçerek tek bir kod tabanında kalabilirsiniz. Doğru proxy stratejisi ile 99%+ başarı oranına ulaşmak mümkündür.






