← Bloga geri dön

Python istekleri: ProxyError, SSLError HATALI_VERSİYON_NUMARASI ve 407 - Pratikte nasıl düzeltilir

Python requests ile proxy kullanırken sık yapılan hataların detaylı analizi: ProxyError, SSLError WRONG_VERSION_NUMBER, 407 Proxy Authentication Required. Her durum için çalışır kod örnekleri.

📅11 Kasım 2026

Eğer Python ile siteleri parse ediyorsanız veya proxy üzerinden istekleri otomatikleştiriyorsanız, er ya da geç üç klasik hata ile karşılaşacaksınız: ProxyError, SSLError: WRONG_VERSION_NUMBER ve HTTP 407 Proxy Authentication Required. Bu yazıda her birinin nedenini inceleyecek ve düzeltmek için çalışır kod göstereceğiz.

Requests'in proxy ile çalışma şekli: temel sözdizimi

requests kütüphanesi, proxy'leri bir sözlük aracılığıyla alır proxies, burada anahtarlar istek şemasını (http ve https) temsil eder ve değerler, isteğe bağlı kimlik doğrulama ile proxy sunucusunun URL'sidir.

import requests

proxies = {
    "http": "http://user:password@proxy_host:port",
    "https": "http://user:password@proxy_host:port",
}

response = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=10)
print(response.json())

Dikkat edin: HTTPS istekleri için bile, proxy şeması genellikle http:// olarak belirtilir, çünkü çoğu proxy sunucusu HTTP protokolü üzerinden CONNECT tünelini kabul eder, SSL ile sarmalar. Eğer proxy için https:// belirtirseniz ve bu desteklenmiyorsa — SSLError alırsınız, bunun analizi aşağıda yapılacaktır.

Eğer SOCKS5 proxy ile çalışıyorsanız, ek bir paket gerekecektir:

pip install requests[socks]

# Ve proxies sözdizimi değişiyor:
proxies = {
    "http": "socks5://user:password@proxy_host:port",
    "https": "socks5://user:password@proxy_host:port",
}

ProxyError: nedenler ve çözümler

requests.exceptions.ProxyError — proxy sunucusuna bağlanmaya çalışırken ortaya çıkan düşük seviyeli ağ istisnalarının bir sarmalayıcısıdır. En sık karşılaşılan dört senaryo vardır.

1. Proxy erişilemez veya adres/port yanlış belirtilmiş

requests.exceptions.ProxyError: HTTPSConnectionPool(host='example.com', port=443):
Max retries exceeded with url: / (Caused by ProxyError('Cannot connect to proxy.',
ConnectionResetError(104, 'Connection reset by peer')))

Host ve portun doğru girildiğinden emin olun ve proxy sunucusunun gerçekten çalıştığını kontrol edin. En hızlı teşhis yöntemi — curl ile bağlanmayı denemektir:

curl -x http://user:password@proxy_host:port https://httpbin.org/ip -v

2. Proxy isteğinizi engelledi (IP veya User-Agent ile yasaklama)

Veri merkezi proxy'leri, hedef siteler tarafından IP aralıklarının anti-fraud sistemleri tarafından bilindiği için sıkça yasaklanır. Eğer hata belirli bir siteye (örneğin, Wildberries, Ozon veya sosyal medya) erişirken sürekli ortaya çıkıyorsa, tüm sitelere değil — sorun proxy'de değil, onun itibarındadır. Bu durumda, rezidans proxy'lerine geçmek yardımcı olur — bunlar gerçek kullanıcıların IP'lerini kullanır ve anti-fraud sistemleri tarafından daha az yasaklanır.

3. Eş zamanlı bağlantı limiti aşıldı

Eğer çoklu iş parçacığı ile parsing yapıyorsanız ve aynı proxy üzerinden yüzlerce bağlantı açıyorsanız, sunucu fazla bağlantıları kapatmaya başlayabilir. Çözüm — requests.adapters.HTTPAdapter ile pool_maxsize ve max_retries sınırlaması kullanmaktır:

from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

session = requests.Session()
retries = Retry(total=3, backoff_factor=1, status_forcelist=[502, 503, 504])
adapter = HTTPAdapter(max_retries=retries, pool_connections=20, pool_maxsize=20)

session.mount("http://", adapter)
session.mount("https://", adapter)

response = session.get("https://httpbin.org/ip", proxies=proxies, timeout=10)

4. Proxy sunucusunda zaman aşımı

Eğer proxy "asılı" kalırsa ve belirlenen zaman aşımından daha uzun sürerse, ProxyError alırsınız, bu da ReadTimeoutError ile sarılır. Zaman aşımını makul bir değere (genellikle 15-30 saniye yeterlidir) artırın ve istisnayı ayrı olarak işleyin:

try:
    response = requests.get(url, proxies=proxies, timeout=20)
except requests.exceptions.ProxyError as e:
    print(f"Proxy ile ilgili sorun: {e}")
except requests.exceptions.Timeout:
    print("Proxy belirlenen süre içinde yanıt vermedi")

SSLError WRONG_VERSION_NUMBER: sorun analizi

Bu hata, ilk bakışta en anlaşılmaz olanlardan biridir, ancak gerçekte neredeyse her zaman tek bir nedeni vardır.

requests.exceptions.SSLError: HTTPSConnectionPool(host='example.com', port=443):
Max retries exceeded with url: / (Caused by SSLError(SSLError(1, '[SSL:
WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1123)')))

WRONG_VERSION_NUMBER, istemcinin SSL/TLS el sıkışmasını gerçekleştirmeye çalıştığı, ancak sunucunun normal HTTP trafiği beklediği anlamına gelir (şifreleme olmadan). En sık neden, proxies sözlüğünde yanlış belirtilmiş proxy şemasında yatmaktadır.

Sık yapılan hata: proxy sunucusunun adresinde https:// yerine http:// belirtmektir. Çoğu HTTP(S) proxy, HTTPS trafiğini CONNECT mekanizması aracılığıyla proxy'lerken bile normal HTTP üzerinden bağlantı kabul eder.

# YANLIŞ — WRONG_VERSION_NUMBER hatasına neden olur
proxies = {
    "http": "https://user:password@proxy_host:port",
    "https": "https://user:password@proxy_host:port",
}

# DOĞRU
proxies = {
    "http": "http://user:password@proxy_host:port",
    "https": "http://user:password@proxy_host:port",
}

İkinci sık neden — fiziksel olarak TLS'yi desteklemeyen bir port. Örneğin, eğer proxy sağlayıcınız sadece HTTP trafiği için 8080 portunu ayırdıysa ve siz doğrudan (CONNECT'i atlayarak) TLS bağlantısı kurmaya çalışıyorsanız, sunucu TLS el sıkışması yerine normal metinle yanıt verecek ve OpenSSL istemci kütüphanesi bu hatayı verecektir. Proxy sağlayıcınızın belgelerinde, her bir portta hangi portların ve protokollerin (HTTP/HTTPS/SOCKS5) mevcut olduğunu kontrol edin.

Üçüncü bir seçenek — socket veya üçüncü taraf kütüphaneleri kullanarak proxy ile doğrudan TCP bağlantısı kuruyorsunuz, standart requests mekanizmasını atlayarak. Bu durumda, TLS sarmalamasının yalnızca gerçek hedef site için uygulandığından emin olun, proxy ile bağlantı için değil.

407 Proxy Authentication Required: kimlik doğrulama

407 yanıt kodu — proxy sunucuları için standart 401'in bir eşdeğeridir. Bu, sunucunun kimlik doğrulama talep ettiği anlamına gelir ve siz ya bunu iletmediniz ya da yanlış bir formatta ilettiniz.

Yöntem 1: URL'de doğrudan kullanıcı adı ve şifre

proxies = {
    "http": "http://login:password@proxy_host:port",
    "https": "http://login:password@proxy_host:port",
}

response = requests.get("https://httpbin.org/ip", proxies=proxies)

Bu yöntem en basit olanıdır, ancak eğer kullanıcı adı veya şifrede özel karakterler varsa (örneğin, @, :, /), bunları urllib.parse.quote ile kaçırmanız gerekir:

from urllib.parse import quote

login = quote("user@domain")
password = quote("p@ssw:ord!")

proxy_url = f"http://{login}:{password}@proxy_host:port"
proxies = {"http": proxy_url, "https": proxy_url}

Yöntem 2: Proxy-Authorization başlığını manuel olarak eklemek

Eğer proxy sağlayıcınız standart bir kimlik doğrulama şeması kullanmıyorsa veya daha fazla kontrol istiyorsanız, başlığı manuel olarak base64 kodlaması ile oluşturabilirsiniz:

import base64
import requests

login = "user"
password = "password"
credentials = base64.b64encode(f"{login}:{password}".encode()).decode()

headers = {
    "Proxy-Authorization": f"Basic {credentials}"
}

proxies = {
    "http": "http://proxy_host:port",
    "https": "http://proxy_host:port",
}

response = requests.get(
    "https://httpbin.org/ip",
    proxies=proxies,
    headers=headers,
    timeout=10
)

Önemli: bazı proxy sağlayıcıları, kimlik doğrulamayı kullanıcı adı/şifreye değil, belirli bir statik IP (whitelist) ile ilişkilendirir. Eğer IP'nizi değiştirirseniz (örneğin, VPN üzerinden çalışıyorsanız veya dinamik IP sağlayıcısı kullanıyorsanız), 407 hatası doğru kimlik bilgileri ile bile ortaya çıkabilir — çünkü mevcut dış IP'niz proxy tarafında beyaz listeye alınmamıştır. Çözüm — sağlayıcının kullanıcı paneline girip izin verilen IP listesini güncellemek veya IP-whitelist yerine kullanıcı adı/şifre ile kimlik doğrulamaya geçmektir.

Retry mantığı ve istisna işleme

Pratikte proxy hataları nadiren tek seferlik olur — özellikle toplu parsing sırasında. Kodun doğru mimarisi, her hatayı ayrı olarak gecikme ile tekrar denemeyi ve kaydetmeyi öngörmelidir.

import time
import requests
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def fetch_with_retry(url, proxies, max_retries=3, backoff=2):
    for attempt in range(1, max_retries + 1):
        try:
            response = requests.get(url, proxies=proxies, timeout=15)
            response.raise_for_status()
            return response
        except requests.exceptions.ProxyError as e:
            logger.warning(f"[Deneme {attempt}] ProxyError: {e}")
        except requests.exceptions.SSLError as e:
            logger.warning(f"[Deneme {attempt}] SSLError: {e}")
        except requests.exceptions.HTTPError as e:
            if response.status_code == 407:
                logger.error("407: kullanıcı adı/şifreyi veya proxy IP whitelist'ini kontrol edin")
                break
            logger.warning(f"[Deneme {attempt}] HTTPError: {e}")
        except requests.exceptions.Timeout:
            logger.warning(f"[Deneme {attempt}] Bağlantı zaman aşımı")

        time.sleep(backoff * attempt)

    raise RuntimeError(f"{url} alınamadı, {max_retries} denemeden sonra")

Bu yaklaşım, hata ayıklama saatlerini tasarruf ettirir: scriptiniz ilk ağ sorununda çökme yerine, her denemede belirli bir hata türünü gösteren anlaşılır bir log alırsınız.

Proxy döngüsü ve yasaklarla mücadele

Eğer ProxyError ve 407 genellikle kod ayarları ile ilgiliyse, toplu yasaklamalar ve belirli alan adlarında sürekli bağlantı reddetmeleri neredeyse her zaman IP havuzunun kalitesi ile ilgilidir. Marketplace'lerde (Wildberries, Ozon, Avito) veya sosyal medya ile çalışırken, her istek için veya belirli bir aralıkta IP döngüsü önerilir.

import random

proxy_pool = [
    "http://user:[email protected]:8000",
    "http://user:[email protected]:8000",
    "http://user:[email protected]:8000",
]

def get_random_proxy():
    proxy = random.choice(proxy_pool)
    return {"http": proxy, "https": proxy}

response = requests.get(url, proxies=get_random_proxy(), timeout=15)

Üretim ortamındaki parserlar için genellikle sağlayıcı tarafında otomatik döngü ile proxy almak daha uygundur — bu durumda IP listesini kendiniz saklamanıza gerek kalmaz, döngü şeffaf bir şekilde tek bir endpoint üzerinden gerçekleşir. Bu durumda rezidans proxy'leri özellikle sert bot koruma sistemlerini aşmak için iyi bir seçimdir, ayrıca veri merkezi proxy'leri ise istek hızının önemli olduğu durumlarda iyi bir seçimdir, hedef site veri merkezi aralıklarını agresif bir şekilde engellemiyorsa.

Proxy türü Hız Yasaklama riski Görevler
Veri merkezi Yüksek Orta-yüksek Açık API'leri hızlı bir şekilde parse etme
Rezidans Orta Düşük Marketplace'leri, sosyal medyayı parse etme
Mobil Orta-düşük Minimum Sert bot koruma sistemleri ile çalışma

Session, zaman aşımı ve SSL doğrulaması

Uzun ömürlü scriptler (örneğin, döngüsel parserlar) için, ayrı çağrılar yerine requests.Session() kullanmak mantıklıdır. Session, TCP bağlantılarını yeniden kullanır, bu da proxy sunucusuna olan yükü azaltır ve büyük miktarda isteklerde ProxyError sayısını düşürür.

session = requests.Session()
session.proxies.update({
    "http": "http://user:password@proxy_host:port",
    "https": "http://user:password@proxy_host:port",
})

for url in urls_list:
    try:
        resp = session.get(url, timeout=15)
        print(resp.status_code, url)
    except requests.exceptions.RequestException as e:
        print(f"{url} üzerinde hata: {e}")

Ayrıca verify parametresini ayrı olarak belirtmek önemlidir. Eğer proxy, SSL sertifikasını kendisi değiştiriyorsa (debug için MITM proxy veya bazı kurumsal proxy'ler), requests sertifika uyuşmazlığı nedeniyle hata verebilir. Doğrulamayı tamamen devre dışı bırakmak (verify=False) yalnızca test ortamında yapılmalıdır — üretim ortamında bu, "adam ortada" saldırıları riski oluşturur:

# Sadece yerel hata ayıklama için!
response = requests.get(url, proxies=proxies, verify=False, timeout=15)

# Doğru yöntem — proxy'nin güvenilir sertifikasının yolunu belirtmek
response = requests.get(url, proxies=proxies, verify="/path/to/proxy_cert.pem")

Hata teşhis kontrol listesi

Eğer script proxy hatası ile çöküyorsa, bu listeyi yukarıdan aşağıya kontrol edin — %90 oranında sorun ilk üç maddede bulunacaktır.

  1. proxies sözlüğündeki şemayı kontrol edin — neredeyse her zaman http:// olmalıdır, hatta HTTPS istekleri için bile.
  2. Proxy'yi doğrudan curl -x ile test edin, böylece kod tarafındaki sorunu dışlayın.
  3. Kullanıcı adı ve şifrenin URL'de kaçırılmamış özel karakterler içermediğinden emin olun.
  4. Proxy'nin belirli bir IP'ye (whitelist) bağlı olmadığını, kullanıcı adı/şifre ile kimlik doğrulama yapıldığını kontrol edin.
  5. Proxy'nin çalışmadığını düşünmeden önce timeout'u 15-30 saniyeye çıkarın.
  6. Eğer hata yalnızca belirli bir sitede çıkıyorsa — sorun IP'nin itibarıdır, kodda değil.
  7. Tek seferlik denemeler yerine, eksponansiyel gecikme ile retry mantığı ekleyin.
  8. Toplu parsing yaparken, tüm istekler için tek bir statik proxy yerine IP döngüsü kullanın.

Sonuç

Python requests'ta çoğu proxy hatası üç şeye dayanır: proxy URL'sindeki yanlış şema (http yerine https), kimlik doğrulamanın eksikliği veya yanlış formatı ve IP havuzunun kalitesi. ProxyError genellikle bağlantı sorunu veya IP yasaklaması hakkında bilgi verir, SSLError WRONG_VERSION_NUMBER neredeyse her zaman yanlış proxy şemasını gösterir, ve 407 — kullanıcı adı/şifre veya whitelist ile ilgili bir sorunu işaret eder.

Eğer marketplace'lerde veya sosyal medyada parsing yaparken yasaklar ve 407 hataları ile sıkça karşılaşıyorsanız, yalnızca kodu değil, proxy kaynağını da gözden geçirmeniz gerekir. Düşük yasak oranı ile stabil bir parsing için rezidans proxy'lerini denemenizi öneririz — bunlar gerçek IP adreslerini kullanır ve korumalı sitelerde ProxyError alma olasılığı çok daha düşüktür. Eğer önceliğiniz hız ve istek hacmi ise, karmaşık bot koruma sistemlerini aşmak yerine, veri merkezi proxy'lerine göz atın — bunlar daha ucuz ve basit parsing görevleri için daha hızlıdır.