Python requests ile Proxy Kullanımı
requests kütüphanesinde proxy tek bir sözlükle tanımlanır; ama anahtarların anlamı, SOCKS desteği ve ortam değişkenleriyle etkileşim sık sık yanlış anlaşılır. Bu rehber üretim ortamına uygun bir yapıyı adım adım kurar.
- proxies sözlüğü ve anahtar mantığı
- socks5h ile DNS proxy tarafında
- Session, timeout ve Retry
En basit kullanım ve IP doğrulama
proxies sözlüğündeki anahtar (http veya https) hedef adresin şemasını, değer ise proxy'nin adresini belirtir. HTTPS siteler için de proxy adresi genellikle http:// ile başlar.
import requests
PROXY = "http://kullanici:sifre@proxy.example.com:8000"
proxies = {
"http": PROXY, # http:// ile başlayan hedefler için
"https": PROXY, # https:// ile başlayan hedefler için
}
r = requests.get(
"https://api.ipify.org?format=json",
proxies=proxies,
timeout=(5, 15), # (bağlantı, okuma) saniye
)
r.raise_for_status()
print("Çıkış IP:", r.json()["ip"])from urllib.parse import quote
kullanici = "kullanici"
sifre = quote("p@ss:42", safe="") # -> p%40ss%3A42
PROXY = f"http://{kullanici}:{sifre}@proxy.example.com:8000"Yalnız "http" anahtarını tanımlarsanız https:// adreslerine yapılan istekler proxy’siz gider. Bu, “proxy çalışıyor ama IP değişmiyor” şikâyetinin en yaygın nedenidir.
SOCKS5 proxy: socks5 ve socks5h farkı
SOCKS desteği için ek paket gerekir. socks5:// şemasında alan adı sizin makinenizde çözülür; socks5h:// şemasında ise ad proxy'ye gönderilir ve DNS sorgusu proxy tarafında yapılır.
pip install "requests[socks]"import requests
PROXY = "socks5h://kullanici:sifre@proxy.example.com:1080"
proxies = {"http": PROXY, "https": PROXY}
r = requests.get("https://api.ipify.org?format=json", proxies=proxies, timeout=(5, 15))
print(r.json())Hedef sitenin proxy lokasyonuna göre çözümlenmesini istiyorsanız ve yerel DNS sorgularının sızmasını önlemek istiyorsanız socks5h kullanın.
Session, timeout ve otomatik yeniden deneme
Çok sayıda istekte Session kullanmak bağlantıları yeniden kullanır; urllib3 Retry ise geçici hatalarda bekleyerek yeniden dener.
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
PROXY = "http://kullanici:sifre@proxy.example.com:8000"
retry = Retry(
total=3,
connect=3,
read=2,
backoff_factor=0.5, # denemeler arasında artan bekleme
status_forcelist=(429, 500, 502, 503, 504),
allowed_methods=frozenset({"GET", "HEAD"}),
respect_retry_after_header=True,
)
adapter = HTTPAdapter(max_retries=retry, pool_connections=10, pool_maxsize=10)
with requests.Session() as s:
s.trust_env = False # ortamdaki proxy değişkenlerini yok say
s.proxies.update({"http": PROXY, "https": PROXY})
s.mount("http://", adapter)
s.mount("https://", adapter)
try:
r = s.get("https://api.ipify.org?format=json", timeout=(5, 15))
r.raise_for_status()
print(r.json())
except requests.exceptions.ProxyError as e:
print("Proxy hatası (kimlik, port veya erişim):", e)
except requests.exceptions.ConnectTimeout:
print("Proxy'ye bağlanılamadı: zaman aşımı")
except requests.exceptions.ReadTimeout:
print("Hedef yanıt vermedi: okuma zaman aşımı")Session.proxies, trust_env açıkken ortam değişkenlerindeki proxy tanımlarıyla ezilebilir. Bu yüzden ya trust_env=False kullanın ya da proxies parametresini her istekte açıkça verin. trust_env=False aynı zamanda .netrc ve REQUESTS_CA_BUNDLE gibi ortam ayarlarını da devre dışı bırakır.
Ortam değişkenleriyle proxy
Kodu değiştirmeden proxy tanımlamak isterseniz requests, varsayılan olarak HTTP_PROXY, HTTPS_PROXY, ALL_PROXY ve NO_PROXY değişkenlerini okur.
export HTTPS_PROXY="http://kullanici:sifre@proxy.example.com:8000"
export HTTP_PROXY="$HTTPS_PROXY"
export NO_PROXY="localhost,127.0.0.1"
python ip_kontrol.py$env:HTTPS_PROXY = "http://kullanici:sifre@proxy.example.com:8000"
$env:HTTP_PROXY = $env:HTTPS_PROXY
python ip_kontrol.pyrequests ve httpx karşılaştırması
Asenkron iş yükleri için httpx sık tercih edilir. Proxy tanımlama biçimleri birbirine yakındır ama birebir aynı değildir.
| Kriter | requests | httpx |
|---|---|---|
| Proxy tanımı | proxies sözlüğü (şemaya göre) | proxy="..." tek adres; şemaya göre ayrım için mounts |
| SOCKS desteği | requests[socks] ekiyle | httpx[socks] ekiyle |
| Asenkron kullanım | Yok | AsyncClient ile var |
| HTTP/2 | Yok | httpx[http2] ekiyle |
| Yeniden deneme | urllib3 Retry ile ayrıntılı | Taşıma katmanında yalnız bağlantı denemesi (retries) |
| Ortam değişkenleri | Varsayılan olarak okunur | Varsayılan olarak okunur (trust_env) |
httpx’in yeni sürümlerinde tek proxy için proxy= parametresi kullanılır; eski proxies= parametresi kaldırılmıştır.
httpx ile aynı doğrulama
import httpx
PROXY = "http://kullanici:sifre@proxy.example.com:8000"
with httpx.Client(proxy=PROXY, timeout=15.0) as client:
r = client.get("https://api.ipify.org?format=json")
r.raise_for_status()
print(r.json())Üretime almadan önce
- Proxy adresini ve şifreyi koddan ayırıp ortam değişkeninden veya gizli yapılandırmadan okuyun.
- Her isteğe bağlantı ve okuma zaman aşımı verin.
- Yeniden deneme sayısını sınırlayın; 4xx kimlik hatalarını yeniden denemeyin.
- Eş zamanlı iş parçacığı sayısını paketinizin bağlantı kurallarına göre ayarlayın.
- Çalışmaya başlarken çıkış IP’sini bir kez doğrulayıp loglayın.
- Hedef sitenin kullanım koşullarına ve istek hızı sınırlarına uyun.
Sorun giderme
Sıkça Sorulan Sorular
proxies sözlüğünde https anahtarına https:// ile başlayan adres mi yazmalıyım?
Genellikle hayır. Anahtar hedef şemayı belirtir; değer ise proxy'nin konuştuğu protokoldür. Sağlayıcınız ayrıca HTTPS proxy (TLS ile korunan proxy bağlantısı) sunmuyorsa değer http:// ile başlamalıdır.
socks5 ile socks5h arasındaki fark nedir?
socks5'te hedef alan adı yerel makinede çözülür ve proxy'ye IP adresi gönderilir. socks5h'de alan adı olduğu gibi proxy'ye iletilir ve çözümleme proxy tarafında yapılır; bu, yerel DNS sorgularının dışarı sızmasını önler.
Her istekte farklı proxy kullanmak için ne yapmalıyım?
proxies parametresini her istekte farklı bir adresle verebilirsiniz. Rotating bir gateway kullanıyorsanız bu işi tek adres üzerinden sağlayıcı yapar; kodunuzda tek proxy tanımı yeterlidir.
Retry, 407 hatasında da yeniden dener mi?
Örnekteki status_forcelist 407'yi içermez ve içermemelidir. Kimlik hatası geçici değildir; yeniden denemek yalnız gereksiz yük oluşturur.
requests ile asenkron istek atabilir miyim?
requests eşzamanlı çalışır. Çok sayıda paralel istek için iş parçacığı havuzu kullanabilir ya da httpx.AsyncClient gibi asenkron bir istemciye geçebilirsiniz.
Proxy şifresini kodun içine yazmak güvenli mi?
Kod depoya gönderilirse şifre de gider. Proxy adresini ortam değişkeninden ya da depoya eklenmeyen bir yapılandırma dosyasından okuyun.
Bunlar da işinize yarayabilir
Doğru proxy ile hemen başlayın
Paketleri karşılaştırın, ihtiyacınıza uygun olanı seçin. Kararsız kaldığınız noktada WhatsApp üzerinden sorabilirsiniz.