Selenium Proxy Auth Sorunu: Neden Standart Yöntemler Yetersiz Kalır?
Selenium, yıllardır web otomasyonunun belkemiği oldu. Ancak iş Selenium proxy auth konusuna gelince, çoğu mühendis duvara toslar. Standart Selenium WebDriver, user:pass formatındaki kimlik doğrulamalı proxy'leri doğal olarak desteklemez. ChromeOptions'a proxy adresi yazabilirsiniz ama kullanıcı adı ve şifreyi nereye koyacağınızı Selenium söylemez — çünkü Chromium'un kendisi HTTP proxy authentication'ı başlıkta iletir ve Selenium bu başlığı kontrol etmez.
Bu eksiklik, özellikle Selenium residential proxies kullanan scraping ve QA ekipleri için ciddi bir engeldir. Residential proxy sağlayıcıları neredeyse her zaman kimlik doğrulama gerektirir; datacenter proxy'ler bile artık token-based auth kullanıyor. Bu rehberde, bu sorunu beş farklı açıdan çözeceğiz: selenium-wire ile Chrome'da auth, Firefox profil bazlı proxy, parmak izi azaltma, dönen proxy havuzu ve konteyner tabanlı ölçekleme.
Chrome + selenium-wire: Kimlik Doğrulamalı Proxy'nin En Temiz Çözümü
selenium-wire, Selenium'un üzerinde ince bir katman olarak çalışır ve tüm HTTP trafiğini yakalayıp modifiye etmenize olanak tanır. En büyük avantajı: user:pass formatındaki proxy URL'lerini doğrudan kabul eder ve Selenium'un yapamadığını yapar — Proxy-Authorization başlığını otomatik ekler.
Kurulum ve Temel Kullanım
pip install selenium-wire selenium
from seleniumwire import webdriver
from selenium.webdriver.chrome.options import Options
# ProxyHat residential proxy — ülke hedefleme ile
PROXY_URL = "http://user-country-US:PASSWORD@gate.proxyhat.com:8080"
options = Options()
options.add_argument("--headless=new")
options.add_argument("--disable-gpu")
options.add_argument("--no-sandbox")
# selenium-wire, proxy'yi selenium_options yerine kendi config'inde alır
seleniumwire_options = {
"proxy": {
"http": PROXY_URL,
"https": PROXY_URL,
"no_proxy": "localhost,127.0.0.1",
},
"verify_ssl": False,
}
driver = webdriver.Chrome(
options=options,
seleniumwire_options=seleniumwire_options,
)
driver.get("https://httpbin.org/ip")
print(driver.page_source)
driver.quit()
Dikkat edilmesi gerekenler:
- selenium-wire, trafiği bir yerel proxy üzerinden yönlendirir. Bu, ekstra bir katman anlamına gelir ve hafif gecikme ekler (genellikle <50ms).
- Header manipulation için
driver.requestsnesnesine erişebilirsiniz — scraping sonrası analiz için paha biçilmez. - Sticky session istiyorsanız, kullanıcı adında
session-bayrağını kullanın:user-country-US-session-abc123:PASSWORD.
Header ve İstek Müdahalesi
selenium-wire'ın gerçek gücü, isteklere müdahale edebilme yeteneğidir. Anti-bot sistemleri belli başlıkları kontrol eder — bunları interceptor ile değiştirebilirsiniz:
def interceptor(request):
# Anti-fingerprint: şüpheli başlıkları kaldır
del request.headers["sec-ch-ua"]
del request.headers["sec-ch-ua-platform"]
request.headers["Accept-Language"] = "en-US,en;q=0.9"
driver.request_interceptor = interceptor
driver.get("https://example.com")
Firefox: Profil Bazlı Proxy Yapılandırması
Firefox, Chrome'dan farklı olarak proxy ayarlarını doğrudan profil tercihlerinde (prefs) saklar. Bu, selenium-wire'a ihtiyaç duymadan kimlik doğrulamalı proxy kurmanın bir yoludur — ancak bir tuzağı vardır: Firefox da user:pass'ı proxy URL'sinden doğrudan almaz. Bunun yerine, bir proxy auto-config (PAC) dosyası veya yerleşik kimlik doğrulama mekanizması kullanmanız gerekir.
En pratik yöntem, Firefox profilinde proxy ayarlarını yapılandırmak ve kimlik doğrulamayı bir uzantı (extension) ile halletmektir:
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
import zipfile, os, tempfile
# ProxyHat SOCKS5 — şehir hedefleme ile
PROXY_HOST = "gate.proxyhat.com"
PROXY_PORT = 1080
PROXY_USER = "user-country-DE-city-berlin"
PROXY_PASS = "PASSWORD"
def create_proxy_auth_extension(host, port, user, password):
"""Geçici bir Firefox uzantısı oluşturur ki proxy auth popup'ını otomatik doldursun."""
manifest_json = """
{
"version": "1.0.0",
"name": "Proxy Auth Helper",
"manifest_version": 2,
"background": {"scripts": ["background.js"]},
"permissions": ["webRequest","webRequestBlocking","<all_urls>"]
}
"""
background_js = """
var authCredentials = {
username: '%s',
password: '%s'
};
browser.webRequest.onAuthRequired.addListener(
function(details) {
return {authCredentials: authCredentials};
},
{urls: ["<all_urls>"]},
["blocking"]
);
""" % (user, password)
tmp_dir = tempfile.mkdtemp()
ext_path = os.path.join(tmp_dir, "proxy_auth.xpi")
with zipfile.ZipFile(ext_path, "w") as zp:
zp.writestr("manifest.json", manifest_json)
zp.writestr("background.js", background_js)
return ext_path
options = Options()
options.add_argument("--headless")
options.set_preference("network.proxy.type", 1)
options.set_preference("network.proxy.socks", PROXY_HOST)
options.set_preference("network.proxy.socks_port", PROXY_PORT)
options.set_preference("network.proxy.socks_remote_dns", True)
ext_path = create_proxy_auth_extension(
PROXY_HOST, PROXY_PORT, PROXY_USER, PROXY_PASS
)
options.add_extension(ext_path)
driver = webdriver.Firefox(options=options)
driver.get("https://httpbin.org/ip")
print(driver.page_source)
driver.quit()
Bu yöntem, Firefox'un Manifest V2 uzantı API'sini kullanır. Mozilla'nın Manifest V3 geçişi nedeniyle, 2025 sonrasında bu kalıbı güncellemeniz gerekebilir — o zamana kadar declarativeNetRequest ile benzer bir yaklaşım mümkün olacaktır.
Selenium Stealth: Parmak İzini Azaltma Stratejileri
Proxy kullanmak IP tabanlı engellemeyi aşar ama bot tespit sistemleri IP'den çok daha fazlasına bakar. Selenium stealth teknikleri, WebDriver'ın otomasyon izlerini minimize eder. İki temel yaklaşım var: selenium-stealth kütüphanesi ve selenium-driverless (CDP-tabanlı).
selenium-stealth ile Temel Gizlenme
from selenium import webdriver
from selenium_stealth import stealth
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option("useAutomationExtension", False)
driver = webdriver.Chrome(options=options)
stealth(driver,
languages=["en-US", "en"],
vendor="Google Inc.",
platform="Win32",
webgl_vendor="Intel Inc.",
renderer="Intel Iris OpenGL Engine",
fix_hairline=True,
)
# navigator.webdriver = true izini kaldır
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": "Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"
})
driver.get("https://bot.sannysoft.com")
print("Stealth test sonuçlarını kontrol edin")
driver.quit()
selenium-driverless: Daha Derin Bir Yaklaşım
selenium-driverless, Chrome DevTools Protocol (CDP) üzerinden çalışır ve WebDriver'ın izlerini daha derin seviyede kaldırır. navigator.webdriver bayrağını CDP seviyesinde devre dışı bırakır, Runtime.enable izlerini temizler ve daha fazlası.
import asyncio
from selenium_driverless import webdriver as async_webdriver
async def main():
options = async_webdriver.ChromeOptions()
options.add_argument("--headless=new")
driver = await async_webdriver.Chrome(options=options)
await driver.get("https://nowsecure.nl")
# CDP ile gelişmiş stealth
await driver.execute_cdp_cmd("Network.setExtraHTTPHeaders", {
"headers": {"Accept-Language": "en-US,en;q=0.9"}
})
page_source = await driver.page_source
print(page_source[:500])
await driver.quit()
asyncio.run(main())
Stealth hiyerarşisi: Basit siteler için selenium-stealth yeterlidir. Cloudflare Turnstile veya Datadome gibi ileri düzey korumalar için selenium-driverless veya doğrudan CDP kullanımı gerekir. Hiçbiri %100 geçiş garantisi vermez — sürekli güncellenen bir kedi-fare oyunudur.
Dönen Proxy Havuzu: Her Oturuma Yeni IP
Sabit bir proxy ile binlerce sayfa çekmek, IP'nin hızla bloklanmasına neden olur. Çözüm: her yeni WebDriver oturumuna farklı bir IP atayan bir rotating proxy pool deseni. ProxyHat'ın residential ağında, her yeni bağlantı zaten varsayılan olarak dönen IP alır — ama sticky session'lar ve ülke hedeflemesi ile kontrolü elinizde tutmak istersiniz.
Proxy Havuzu Yöneticisi
import itertools
from seleniumwire import webdriver
from selenium.webdriver.chrome.options import Options
# ProxyHat residential proxy havuzu — farklı lokasyonlar
PROXY_CREDENTIALS = [
{"user": "user-country-US", "label": "US-East"},
{"user": "user-country-DE", "label": "DE-Frankfurt"},
{"user": "user-country-GB", "label": "GB-London"},
{"user": "user-country-JP", "label": "JP-Tokyo"},
]
PROXY_PASS = "PASSWORD"
GATEWAY = "gate.proxyhat.com:8080"
def get_proxy_url(credential, session_id=None):
"""Oturum bazlı sticky veya dönen proxy URL'si oluşturur."""
user = credential["user"]
if session_id:
user = f"{user}-session-{session_id}"
return f"http://{user}:{PROXY_PASS}@{GATEWAY}"
def create_driver(proxy_url, headless=True):
options = Options()
if headless:
options.add_argument("--headless=new")
options.add_argument("--disable-gpu")
options.add_argument("--no-sandbox")
sw_options = {
"proxy": {"http": proxy_url, "https": proxy_url},
"verify_ssl": False,
}
return webdriver.Chrome(options=options, seleniumwire_options=sw_options)
class ProxyPool:
def __init__(self, credentials):
self._cycle = itertools.cycle(credentials)
self._active_drivers = []
def get_driver(self, session_id=None):
cred = next(self._cycle)
proxy_url = get_proxy_url(cred, session_id)
driver = create_driver(proxy_url)
self._active_drivers.append(driver)
print(f"[Pool] {cred['label']} üzerinden bağlanıyor — session: {session_id or 'rotating'}")
return driver
def release(self, driver):
driver.quit()
if driver in self._active_drivers:
self._active_drivers.remove(driver)
def cleanup_all(self):
for d in self._active_drivers[:]:
d.quit()
self._active_drivers.clear()
# Kullanım
pool = ProxyPool(PROXY_CREDENTIALS)
for i in range(8):
driver = pool.get_driver(session_id=f"batch{i}")
driver.get("https://httpbin.org/ip")
print(f"Oturum {i}: {driver.find_element('tag name','body').text[:50]}")
pool.release(driver)
Bu desen, itertools.cycle ile round-robin dağıtımı yapar. Üretimde, her proxy'nin başarı oranını takip edip ağırlıklı dağıtım (weighted round-robin) kullanmanız önerilir.
Selenium Grid + Docker: Paralel Scraping Ölçekleme
Tek bir makinede 5-10 WebDriver oturumu çalıştırmak mümkündür. Ama günde 100.000 sayfa çekmeniz gerektiğinde, Selenium Grid ve konteynerizasyon kaçınılmazdır.
Docker Compose ile Grid Kurulumu
# docker-compose.yml
version: '3.8'
services:
selenium-hub:
image: selenium/hub:4.18
ports:
- "4442:4442"
- "4443:4443"
- "4444:4444"
environment:
- SE_SESSION_REQUEST_TIMEOUT=300
- SE_NODE_SESSION_TIMEOUT=300
chrome-node:
image: selenium/node-chrome:4.18
depends_on:
- selenium-hub
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
- SE_NODE_MAX_SESSIONS=4
- SE_NODE_OVERRIDE_MAX_SESSIONS=true
deploy:
replicas: 4
shm_size: '2gb'
Grid üzerinde proxy kullanımı için, her node'un ChromeOptions'ına proxy ayarlarını enjekte etmeniz gerekir. selenium-wire Grid'de ekstra yapılandırma gerektirdiğinden, pratikte iki yaklaşım vardır:
- Yaklaşım A: Her node'a özel bir Docker image oluşturun (selenium-wire yüklü) ve proxy'yi ortam değişkeni ile geçirin.
- Yaklaşım B: Proxy'yi ağ seviyesinde yapılandırın — tüm node trafiğini bir SOCKS5 tüneli üzerinden yönlendirin. Bu, uygulama kodunu değiştirmez ama IP rotasyonu daha az esnek olur.
Grid Üzerinde Paralel Scraping
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from concurrent.futures import ThreadPoolExecutor, as_completed
HUB_URL = "http://localhost:4444/wd/hub"
PROXY_URL = "http://user-country-US:PASSWORD@gate.proxyhat.com:8080"
# NOT: Grid'de selenium-wire kullanılamadığından,
# proxy auth için Chrome uzantısı kullanılır
def create_proxy_auth_extension(proxy_url):
from urllib.parse import urlparse
parsed = urlparse(proxy_url)
user = parsed.username
password = parsed.password
host = parsed.hostname
port = parsed.port
import zipfile, tempfile, os
manifest = '{"version":"1.0","name":"proxy_auth","manifest_version":2,"permissions":["webRequest","webRequestBlocking","<all_urls>"],"background":{"scripts":["bg.js"]}}'
bg_js = f'var c={{username:"{user}",password:"{password}"}};chrome.webRequest.onAuthRequired.addListener(function(d){{return{{authCredentials:c}}}},{{urls:["<all_urls>"]}},["blocking"]);'
tmp = tempfile.mkdtemp()
path = os.path.join(tmp, "ext.zip")
with zipfile.ZipFile(path, "w") as z:
z.writestr("manifest.json", manifest)
z.writestr("bg.js", bg_js)
return path
def scrape_page(url, proxy_url=PROXY_URL):
options = Options()
options.add_argument("--headless=new")
options.add_argument("--no-sandbox")
options.add_argument(f"--proxy-server=http://{urlparse(proxy_url).hostname}:{urlparse(proxy_url).port}")
options.add_extension(create_proxy_auth_extension(proxy_url))
driver = webdriver.Remote(
command_executor=HUB_URL,
options=options,
)
try:
driver.get(url)
return {"url": url, "title": driver.title, "status": "ok"}
except Exception as e:
return {"url": url, "error": str(e), "status": "fail"}
finally:
driver.quit()
URLS = ["https://httpbin.org/ip"] * 16 # test için
with ThreadPoolExecutor(max_workers=8) as executor:
futures = {executor.submit(scrape_page, u): u for u in URLS}
for f in as_completed(futures):
result = f.result()
print(f"{result['status'].upper()}: {result.get('title', result.get('error', ''))}")
Selenium vs Playwright: Hangi Durumda Hangisi?
Playwright, 2020'den beri hızla büyüyen bir alternatif. Selenium'un eksikliklerinin çoğunu giderir ama Selenium'un 20 yıllık ekosistem avantajı vardır. Somut bir karşılaştırma:
| Kriter | Selenium | Playwright |
|---|---|---|
| Proxy Auth (user:pass) | selenium-wire veya uzantı gerekir | Doğal destek: proxy: {username, password} |
| Stealth / Anti-bot | selenium-stealth, selenium-driverless eklentileri | Daha temiz CDP entegrasyonu; daha az iz |
| Tarayıcı Desteği | Chrome, Firefox, Edge, Safari (legacy) | Chromium, Firefox, WebKit (tek API) |
| Paralel Çalıştırma | Grid + Docker gerektirir | Yerleşik browser.context() ile kolay |
| Ekosistem Olgunluğu | Çok geniş: Appium, IDE eklentileri, CI entegrasyonları | Büyüyor ama daha dar |
| Mevcut Kod Tabanı | On binlerce proje, çok sayıda rehber | Daha az referans, daha az StackOverflow cevabı |
| Ağ Müdahalesi | selenium-wire ile mümkün | route.intercept() ile doğal ve güçlü |
| Headless Mod | Eski --headless ve yeni --headless=new ayrımı kafa karıştırır |
Tutarlı, varsayılan headless |
Playwright'ı tercih edin eğer:
- Yeni bir proje başlatıyorsanız ve proxy auth doğal destek istiyorsanız.
- Ağ müdahalesi (request interception, mocking) yoğun kullanacaksanız.
- Multi-browser testini tek API ile yapacaksanız.
Selenium'u tercih edin eğer:
- Mevcut bir Selenium kod tabanınız var ve geçiş maliyeti yüksek.
- Appium ile mobil test entegrasyonu gerekiyor.
- Kurumsal CI/CD ortamlarında Grid zaten kurulu ve çalışıyor.
- Selenium IDE ile kaydedilmiş testleriniz var.
Pratik tavsiye: Yeni scraping projeleri için Playwright'ı değerlendirin. Mevcut Selenium projeleri için, bu rehberdeki kalıpları uygulayarak proxy auth ve stealth sorunlarını çözebilirsiniz — tam yeniden yazma gerekmez.
Etik ve Hukuki Değerlendirme
Proxy ve otomasyon kullanırken bazı sınırları bilmek kritiktir:
- robots.txt ve ToS: Bir sitenin hizmet şartları otomatik erişimi yasaklıyorsa, proxy kullanmak bu yasağı aşmaz — sadece tespiti zorlaştırır. Hukuki risk devam eder.
- KVKK / GDPR: Kişisel veri toplayacaksanız, açık rıza gerekir. IP adresleri bile kişisel veri sayılabilir.
- Orantılılık: Hedef sunucuya aşırı yük bindirmeyin. Rate limiting uygulayın — saniyede 5-10 istek, çoğu site için makul bir üst sınırdır.
- Veri kullanımı: Topladığınız veriyi sadece belirttiğiniz amaçla kullanın. Rakip fiyatlarını izlemek genellikle meşrudur; kullanıcı profil verilerini izinsiz toplamak değildir.
Özet: Temel Çıkarımlar
Key Takeaways:
- Selenium proxy auth için en pratik çözüm selenium-wire'dır — Chrome'da
user:passURL'sini doğrudan kabul eder.- Firefox'ta proxy auth, profil tercihleri + uzantı ile çözülür; selenium-wire'a gerek yoktur.
- Selenium stealth için
selenium-stealthtemel,selenium-driverlessileri düzey korumalar içindir.- Dönen proxy havuzu deseni, her WebDriver oturumuna yeni IP atar ve IP bloklanmasını önler.
- Paralel ölçekleme için Selenium Grid + Docker Compose en olgun yaklaşımdır; ancak Playwright'ın yerleşik paralel modeli daha basittir.
- Yeni projelerde Playwright'ı değerlendirin; mevcut Selenium kod tabanları için bu rehberdeki kalıplar yeterlidir.
ProxyHat'ın residential proxy ağı, Selenium entegrasyonunuzun güvenilir omurgasıdır. 190+ ülkede IP havuzu, şehir seviyesi hedefleme ve oturum bazlı sticky session desteği ile scraping ve QA iş yükleriniz için uygun fiyatlı planlar mevcuttur. Detaylı lokasyon listesi için proxy lokasyonları sayfasını inceleyin. Web scraping kullanım senaryolarınız için web scraping kullanım örneği sayfamıza göz atın.






