Python'da aiohttp ile proxy kullanımı
aiohttp ve proxy'ler
aiohttp, Python'un en popüler asenkron HTTP kütüphanesidir. Binlerce eşzamanlı istek göndermeye izin verir; bu da onu parsing ve otomasyon için ideal kılar. aiohttp'deki proxy desteği, büyük ölçekli işler için kilit bir özelliktir.
Temel proxy kullanımı
HTTP proxy'ler
aiohttp'de bir HTTP proxy kullanmanın en basit yolu, istek metodundaki proxy parametresidir:
import aiohttp
import asyncio
async def fetch_with_proxy():
proxy = "http://proxy_ip:port"
async with aiohttp.ClientSession() as session:
async with session.get(
"https://httpbin.org/ip",
proxy=proxy
) as response:
data = await response.json()
print(data)
asyncio.run(fetch_with_proxy())
Kimlik doğrulamalı proxy'ler
Kullanıcı adı ve şifresi olan proxy'ler için BasicAuth kullanın:
import aiohttp
import asyncio
async def fetch_with_auth_proxy():
proxy = "http://proxy_ip:port"
proxy_auth = aiohttp.BasicAuth("username", "password")
async with aiohttp.ClientSession() as session:
async with session.get(
"https://httpbin.org/ip",
proxy=proxy,
proxy_auth=proxy_auth
) as response:
data = await response.json()
print(data)
asyncio.run(fetch_with_auth_proxy())
Alternatif bir format, kimlik bilgilerini URL içine koymaktır:
proxy = "http://username:password@proxy_ip:port"
SOCKS5 proxy'ler
aiohttp-socks kurulumu
aiohttp, SOCKS'u yerel olarak desteklemez. aiohttp-socks kurun:
pip install aiohttp-socks
Kullanım
import aiohttp
from aiohttp_socks import ProxyConnector
async def fetch_with_socks():
connector = ProxyConnector.from_url("socks5://user:pass@proxy_ip:port")
async with aiohttp.ClientSession(connector=connector) as session:
async with session.get("https://httpbin.org/ip") as response:
data = await response.json()
print(data)
asyncio.run(fetch_with_socks())
Desteklenen protokoller
ProxyConnector şunları destekler:
- socks5://
- socks4://
- http://
- https://
Proxy rotasyonu
Basit rotasyon
import aiohttp
import asyncio
import random
PROXIES = [
"http://user:pass@proxy1:port",
"http://user:pass@proxy2:port",
"http://user:pass@proxy3:port",
]
async def fetch_with_rotation(url):
proxy = random.choice(PROXIES)
async with aiohttp.ClientSession() as session:
async with session.get(url, proxy=proxy) as response:
return await response.text()
async def main():
urls = ["https://example.com"] * 10
tasks = [fetch_with_rotation(url) for url in urls]
results = await asyncio.gather(*tasks, return_exceptions=True)
for r in results:
if isinstance(r, Exception):
print(f"Error: {r}")
else:
print(f"OK: {len(r)} bytes")
asyncio.run(main())
Başarısız proxy'leri devre dışı bırakan rotasyon
import aiohttp
import asyncio
from collections import deque
class ProxyRotator:
def __init__(self, proxies):
self.proxies = deque(proxies)
self.failed = set()
def get_proxy(self):
for _ in range(len(self.proxies)):
proxy = self.proxies[0]
self.proxies.rotate(-1)
if proxy not in self.failed:
return proxy
raise Exception("All proxies failed")
def mark_failed(self, proxy):
self.failed.add(proxy)
def mark_success(self, proxy):
self.failed.discard(proxy)
async def fetch(session, url, rotator, retries=3):
for attempt in range(retries):
proxy = rotator.get_proxy()
try:
async with session.get(url, proxy=proxy, timeout=aiohttp.ClientTimeout(total=10)) as resp:
if resp.status == 200:
rotator.mark_success(proxy)
return await resp.text()
elif resp.status == 403:
rotator.mark_failed(proxy)
except Exception:
rotator.mark_failed(proxy)
return None
Limitli eşzamanlı istekler
Eşzamanlılık kontrolü için semafor
import aiohttp
import asyncio
async def fetch(session, url, proxy, semaphore):
async with semaphore:
try:
async with session.get(url, proxy=proxy, timeout=aiohttp.ClientTimeout(total=15)) as resp:
return await resp.text()
except Exception as e:
return None
async def main():
urls = [f"https://example.com/page/{i}" for i in range(100)]
proxy = "http://user:pass@proxy:port"
semaphore = asyncio.Semaphore(10) # en fazla 10 eşzamanlı
async with aiohttp.ClientSession() as session:
tasks = [fetch(session, url, proxy, semaphore) for url in urls]
results = await asyncio.gather(*tasks)
success = sum(1 for r in results if r)
print(f"Success: {success}/{len(urls)}")
asyncio.run(main())
Oturum yapılandırması
Timeout
timeout = aiohttp.ClientTimeout(
total=30, # toplam timeout
connect=10, # bağlantı timeout'u
sock_read=10 # soket okuma timeout'u
)
session = aiohttp.ClientSession(timeout=timeout)
Header'lar
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Accept": "text/html,application/xhtml+xml",
"Accept-Language": "en-US,en;q=0.9",
}
session = aiohttp.ClientSession(headers=headers)
SSL
# SSL doğrulamasını kapatma (test için)
import ssl
ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
session = aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=ssl_context))
Hata yönetimi
import aiohttp
async def safe_fetch(session, url, proxy):
try:
async with session.get(url, proxy=proxy) as resp:
if resp.status == 200:
return await resp.text()
elif resp.status == 407:
print("Proxy authentication required")
elif resp.status == 403:
print("Forbidden - proxy might be banned")
elif resp.status == 429:
print("Rate limited - slow down")
return None
except aiohttp.ClientProxyConnectionError:
print("Cannot connect to proxy")
except aiohttp.ClientConnectorError:
print("Connection error")
except asyncio.TimeoutError:
print("Request timed out")
except Exception as e:
print(f"Unexpected error: {e}")
return None
aiohttp vs requests
| Parametre | aiohttp | requests |
|---|---|---|
| Asenkronluk | Evet (asyncio) | Hayır (senkron) |
| Eşzamanlılık | Binlerce | Thread sayısıyla sınırlı |
| Hız | Yüksek | Orta |
| Proxy'ler | HTTP, SOCKS (aiohttp-socks ile) | HTTP, SOCKS |
| Karmaşıklık | Daha yüksek (async/await) | Basit |
| Bellek | Daha verimli | Daha çok tüketir |
Sonuç
Python'da asenkron proxy kullanımı için en iyi seçim aiohttp'dir. HTTP ve SOCKS5 desteği (aiohttp-socks ile), proxy rotasyonu, eşzamanlılık kontrolü ve hata yönetimi onu büyük ölçekli parsing ve otomasyon için güçlü bir araç yapar.
