Proxy Tarayıcıda Çalışırken Kodda Neden Çalışmaz: Tam Sorun Analizi
Klasik durum: Proxy'yi tarayıcıda ayarladınız, siteyi açtınız - her şey yolunda. Aynı proxy ile bir betik çalıştırdınız - bağlantı hatası, zaman aşımı veya yasaklama alıyorsunuz. Neden böyle olduğunu ve bunu nasıl düzeltebileceğinizi inceliyoruz.
Tarayıcıdan Gelen İstek Koddan Nasıl Farklıdır?
Proxy üzerinden bir siteyi tarayıcıda açtığınızda, basit bir HTTP isteğinden çok daha fazlası gerçekleşir. Tarayıcı otomatik olarak şunları yapar:
- Tam bir başlık seti gönderir (User-Agent, Accept, Accept-Language, Accept-Encoding)
- Doğru şifre setiyle TLS el sıkışmasını gerçekleştirir
- Yönlendirmeleri (redirects) ve çerezleri (cookies) yönetir
- JavaScript çalıştırır ve bağımlı kaynakları yükler
- DNS yanıtlarını ve sertifikaları önbelleğe alır
Koddan gelen minimal bir istek, sunucuya tamamen farklı görünür; bir robottan çok bir insana benzer. Proxy doğru çalışsa bile, hedef site tam olarak sizin betiğinizi engelleyebilir.
Proxy Kimlik Doğrulama Sorunları
En yaygın neden, kullanıcı adı ve şifrenin yanlış iletilmesidir. Tarayıcı kimlik bilgilerini girmek için bir açılır pencere gösterirken, kodda bunu açıkça belirtmeniz gerekir.
Yanlış URL Formatı
Sık yapılan bir hata, şemanın atlanması veya özel karakterlerin yanlış kodlanmasıdır:
# Yanlış
proxy = "user:pass@proxy.example.com:8080"
# Doğru
proxy = "http://user:pass@proxy.example.com:8080"
# Eğer şifrede özel karakterler (@, :, /) varsa
from urllib.parse import quote
password = quote("p@ss:word/123", safe="")
proxy = f"http://user:{password}@proxy.example.com:8080"
IP'ye Göre Kimlik Doğrulama vs. Kullanıcı Adı/Şifre
Bazı proxy sağlayıcıları IP adresine göre bir beyaz liste (whitelist) kullanır. Tarayıcınız bilgisayarınızda çalışır çünkü IP'niz beyaz listeye eklenmiştir. Ancak sunucudaki betik çalışmaz, çünkü sunucunun IP'si farklıdır.
Sağlayıcınızın panelinden hangi kimlik doğrulama yönteminin kullanıldığını ve beyaz listeye hangi IP'lerin eklendiğini kontrol edin.
HTTP/HTTPS/SOCKS Protokol Uyuşmazlıkları
Tarayıcı genellikle proxy türünü otomatik olarak algılar. Kodda bunu açıkça belirtmeniz gerekir ve protokoldaki bir hata sessiz bir reddedilmeye yol açar.
| Proxy Türü | URL Şeması | Özellikler |
|---|---|---|
| HTTP Proxy | http:// |
CONNECT üzerinden HTTP ve HTTPS için çalışır |
| HTTPS Proxy | https:// |
Proxy ile şifreli bağlantı |
| SOCKS4 | socks4:// |
Kimlik doğrulama yok, yalnızca IPv4 |
| SOCKS5 | socks5:// |
Kimlik doğrulama, UDP, IPv6 ile |
| SOCKS5h | socks5h:// |
Proxy üzerinden DNS çözümleme |
Kritik nokta: Eğer SOCKS5 proxy'niz varsa ancak http:// şemasını belirtiyorsanız, bağlantı kurulamaz. Kütüphane SOCKS sunucusuna HTTP protokolüyle konuşmaya çalışacaktır.
Eksik Başlıklar ve Parmak İzi (Fingerprint)
Proxy doğru çalışsa bile, hedef site şüpheli başlıklardan dolayı isteği engelleyebilir. Karşılaştırın:
Tarayıcıdan Gelen İstek
GET /api/data HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Varsayılan requests İstemi
GET /api/data HTTP/1.1
Host: example.com
User-Agent: python-requests/2.28.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Fark açıktır. Bot koruması olan bir site, tarayıcı dışından geldiğini anında tespit edecektir.
Maskeleme İçin Minimum Başlık Seti
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
"Cache-Control": "max-age=0"
}
SSL Sertifikaları ve Doğrulama
Tarayıcı, yerleşik bir kök sertifika deposuna sahiptir ve çeşitli SSL yapılandırmalarını işleyebilir. Kodda şu sorunlar ortaya çıkabilir:
SSL Hatası: CERTIFICATE_VERIFY_FAILED
Bazı proxy'ler trafik denetimi için kendi sertifikalarını kullanır. Tarayıcınız bu sertifikayı güvenilir olarak kabul edebilir, ancak betiğiniz kabul etmeyebilir.
# Hata ayıklama için geçici çözüm (PROD ortamı için DEĞİL!)
import requests
response = requests.get(url, proxies=proxies, verify=False)
# Doğru çözüm — sertifika yolunu belirtmek
response = requests.get(url, proxies=proxies, verify="/path/to/proxy-ca.crt")
Önemli: SSL doğrulamayı devre dışı bırakmak (
verify=False), bağlantıyı MITM saldırılarına karşı savunmasız hale getirir. Yalnızca güvenli bir ortamda hata ayıklama için kullanın.
TLS Parmak İzi (Fingerprint)
Gelişmiş bot sistemleri, bağlantı kurulurken şifrelerin sırasını ve kümesini analiz eden TLS parmak izini inceler. Python requests varsayılan bir küme kullanır, bu da tarayıcıdakinden farklıdır.
Bunu aşmak için özel TLS parmak izine sahip kütüphaneler kullanın:
# Kurulum: pip install curl-cffi
from curl_cffi import requests
response = requests.get(
url,
proxies={"https": proxy},
impersonate="chrome120" # Chrome 120'nin TLS parmak izini taklit eder
)
DNS Sızıntıları ve Çözümleme (Resolving)
Bir diğer gizli sorun DNS çözümlemedir. HTTP proxy kullanıldığında, DNS isteği proxy'yi atlayarak doğrudan makinenizden gidebilir.
Çalışmaya Etkisi
- Site, proxy yerine gerçek DNS çözümleyicinizi görür
- Coğrafi konum yanlış belirlenir
- Bazı siteler, IP ve DNS bölgesindeki eşitsizlikleri engeller
SOCKS5 Çözümü
DNS çözümlemesinin proxy üzerinden yapılması için socks5h:// şemasını socks5:// yerine kullanın — "h" harfi, DNS çözümlemenin proxy tarafında yapılacağı anlamına gelir:
# DNS yerel olarak çözümlenir (sızıntı!)
proxy = "socks5://user:pass@proxy.example.com:1080"
# DNS proxy üzerinden çözümlenir (doğru)
proxy = "socks5h://user:pass@proxy.example.com:1080"
Python, Node.js ve cURL İçin Çalışan Örnekler
Python requests ile
import requests
from urllib.parse import quote
# Proxy bilgileri
proxy_host = "proxy.example.com"
proxy_port = "8080"
proxy_user = "username"
proxy_pass = quote("p@ssword!", safe="") # Özel karakterleri kodla
# Proxy URL'sini oluşturma
proxy_url = f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"
proxies = {
"http": proxy_url,
"https": proxy_url
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
}
try:
response = requests.get(
"https://httpbin.org/ip",
proxies=proxies,
headers=headers,
timeout=30
)
print(f"Durum: {response.status_code}")
print(f"IP: {response.json()}")
except requests.exceptions.ProxyError as e:
print(f"Proxy Hatası: {e}")
except requests.exceptions.ConnectTimeout:
print("Proxy bağlantı zaman aşımı")
Python aiohttp ile (Asenkron)
import aiohttp
import asyncio
async def fetch_with_proxy():
proxy_url = "http://user:pass@proxy.example.com:8080"
async with aiohttp.ClientSession() as session:
async with session.get(
"https://httpbin.org/ip",
proxy=proxy_url,
headers={"User-Agent": "Mozilla/5.0..."}
) as response:
return await response.json()
result = asyncio.run(fetch_with_proxy())
print(result)
Node.js axios ile
const axios = require('axios');
const HttpsProxyAgent = require('https-proxy-agent');
const proxyUrl = 'http://user:pass@proxy.example.com:8080';
const agent = new HttpsProxyAgent(proxyUrl);
axios.get('https://httpbin.org/ip', {
httpsAgent: agent,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...'
}
})
.then(response => console.log(response.data))
.catch(error => console.error('Hata:', error.message));
Node.js node-fetch ve SOCKS ile
const fetch = require('node-fetch');
const { SocksProxyAgent } = require('socks-proxy-agent');
const agent = new SocksProxyAgent('socks5://user:pass@proxy.example.com:1080');
fetch('https://httpbin.org/ip', { agent })
.then(res => res.json())
.then(data => console.log(data));
cURL
# HTTP Proxy
curl -x "http://user:pass@proxy.example.com:8080" \
-H "User-Agent: Mozilla/5.0..." \
https://httpbin.org/ip
# Proxy üzerinden DNS ile SOCKS5 Proxy
curl --socks5-hostname "proxy.example.com:1080" \
--proxy-user "user:pass" \
https://httpbin.org/ip
# Hata ayıklama - tüm bağlantı sürecini göster
curl -v -x "http://user:pass@proxy.example.com:8080" \
https://httpbin.org/ip
Teşhis Kontrol Listesi
Eğer proxy kodda çalışmıyorsa, sırayla şunları kontrol edin:
- Proxy URL Formatı — şema (http://, socks5://) mevcut mu?
- Paroladaki Özel Karakterler — URL kodlaması yapılmış mı?
- Proxy Türü — belirtilen protokol gerçek olanla eşleşiyor mu?
- Kimlik Doğrulama — IP'ye göre mi yoksa kullanıcı adı/şifreye göre mi? Sunucu IP'si beyaz listede mi?
- Başlıklar — User-Agent ve diğer tarayıcı başlıkları eklendi mi?
- SSL — Sertifika hatası var mı?
- DNS — Çözümleme için proxy üzerinden socks5h:// kullanılıyor mu?
- Zaman Aşımları — Bağlantı için yeterli zaman tanındı mı (özellikle konut proxy'leri için)?
Sonuç
Tarayıcı ile kod arasındaki fark detaylardadır: başlıklar, protokoller, SSL, DNS. Tarayıcı bu karmaşıklığı gizlerken, kodda her yönün açıkça yapılandırılması gerekir. URL formatını ve kimlik doğrulamayı kontrol ederek başlayın, ardından tarayıcı başlıklarını ekleyin - bu, sorunların %90'ını çözecektir.
Veri kazıma (scraping) ve otomasyon görevleri için, kararlılık ve düşük engellenme oranı açısından iyi olan konut proxy'leri uygundur - bunlar hakkında daha fazla bilgiyi proxycove.com adresinde bulabilirsiniz.