Mobil Proxy ile Python Veri Toplama
İstekler, httpx, aiohttp ve Scrapy için çalışan proxy kodu — kullanıcıların sıklıkla yanlış kullandığı proxy sözlüğü, gerçek sitelerle etkileşimde bile işe yarayan rotasyon modelleri ve 429 hatası verip durmak yerine Retry-After başlığını dikkate alan geri çekilme mekanizması.
- Standart kütüphane yığınıyla uyumludur — requests, httpx, aiohttp ve Scrapy için özel bir istemciye gerek yoktur.
- Tek bir proxy URL'si — her istemcinin anladığı, http://user:pass@host:port biçimindeki aynı dize.
- İsteğe bağlı döndürme — iş sınırlarında kendi kodunuzdan yeni bir IP'yi tetikleyin.
- Sınırsız bant genişliği — eşzamanlı bağlantı sayısı ve veri yükü boyutu faturayı asla etkilemez.
Standart HTTP(S) ve SOCKS5 uç noktaları — entegrasyon için herhangi bir satıcı SDK’sı gerekmez.
Sabit bir zamanlayıcı yerine, iş sınırlarında yeni bir çıkış IP’si tetikleyin.
İstekler ve httpx: Oturumlar, Proxy Sözlükleri ve CONNECT Tüneli
İstediğiniz işaretleme ilk yanıtta zaten mevcutsa, tarayıcıyı başlatmayın. Bir HTTP istemcisi, bellek ve zaman açısından on kat daha az kaynak tüketir. Her çağrıda TLS’yi yeniden müzakere etmek yerine, bağlantı havuzu ve çerez deposunun istekler arasında yeniden kullanılabilmesi için tek bir Oturum kullanın:
import os
import requests
PROXY = os.environ["PXM2_PROXY"] # http://user:pass@host:port
with requests.Session() as s:
s.proxies.update({"http": PROXY, "https": PROXY})
s.headers.update({
"User-Agent": "Mozilla/5.0 (Linux; Android 14) AppleWebKit/537.36 ...",
"Accept-Language": "en-GB,en;q=0.9",
})
r = s.get("https://example.com/listings", timeout=30)
r.raise_for_status()
İnsanların yanlış anladığı nokta, https girişidir. Hâlâ http:// şeması kullanılır; çünkü bu şema, hedefin protokolünü değil, proxy’ye nasıl ulaşılacağını belirtir. İstemci, proxy üzerinden bir CONNECT tüneli açar ve TLS daha sonra bu tünelin içinde uçtan uca çalışır; dolayısıyla proxy, düz metninizi hiçbir zaman görmez. Bunun yerine oraya https:// yazmak, bir Python proxy'sinin HTTPS için çalışmıyormuş gibi görünmesinin en yaygın nedenidir.
İkinci ayrıntı ise tutarlılıktır: Bir mobil Kullanıcı Aracısı, bir mobil IP adresiyle eşleştirilmelidir. Bir veri merkezi aralığından Android telefon olduğunu iddia etmek, herhangi bir parmak izi tespit katmanının fark edebileceği bir çelişkidir.
httpx, farklı bir anahtar kelimeyle aynı şekilde çalışır — proxy’yi Client yapıcıya aktarın. HTTP/2 kullanmak istediğinizde bunu tercih etmeniz faydalıdır; çünkü tarayıcı benzeri bir protokol sürümü, başlıklarınızda belirtilenlerle istemcinizin davranışları arasındaki tutarsızlıkları bir tane azaltır.
| Kütüphane | Vekaletnamenin nereye gönderileceği | Döner kanca | En uygun olduğu durumlar |
|---|---|---|---|
| requests | Session.proxies sözlüğü veya çağrı başına proxy'ler= | Her vekil için bir oturum | Basit senkron taramalar |
| httpx | İstemcide proxy= ayarı | Proxy başına bir istemci | HTTP/2 ya da tek bir API’da senkron ve asenkron işlemler |
| aiohttp | proxy= tek tek isteklerde | İsteğe bağlı olarak, dolayısıyla döndürme işlemi çok basit | Yüksek eşzamanlılık |
| Scrapy | request.meta["proxy"] | Bir indirme aracı ara yazılımı | Büyük ölçekli yapılandırılmış taramalar |
Özel Karakterler İçeren Vekil Kimlik Bilgileri
A username or password containing an at sign, colon or slash breaks the http://user:pass@host:port format before the client ever opens a connection, because those characters are also the URL's own delimiters. Percent-encode each credential with urllib.parse.quote before building the string — quote(password, safe="") — rather than special-casing whichever character happens to show up this week.
Python’da Proxy Dönüşümü: Round-Robin, Rastgele ve Hata Durumunda Dönüşüm
Burada birbirinden oldukça farklı iki durum söz konusudur ve bunların birbirine karıştırılması kafa karışıklığının büyük bir kısmına neden olmaktadır. Size tek bir dönen uç nokta verilmişse, dönüş işlemi daha üst aşamada gerçekleşir ve kodunuz yalnızca ne zaman yeni bir IP isteyeceğine karar verir. Uç noktaların bir listesine sahipseniz, dönüş politikasını kendiniz belirlersiniz.
İkinci durumda, istek başına değil, her Oturum için bir proxy atayın. Bir Oturum, bağlantı havuzunu ve çerez havuzunu barındırır; bu nedenle, işlem devam ederken proxy’yi değiştirmek, proxy kullanmanın amacını boşa çıkarır:
import itertools
import requests
PROXIES = [
"http://user:pass@host:10001",
"http://user:pass@host:10002",
"http://user:pass@host:10003",
]
def sessions_for(proxies):
"One Session per exit IP, reused for the life of a job."
out = []
for p in proxies:
s = requests.Session()
s.proxies.update({"http": p, "https": p})
out.append(s)
return out
pool = itertools.cycle(sessions_for(PROXIES))
for job in jobs:
session = next(pool) # a whole job stays on one IP
run(session, job)
Döngünün ne yapmadığını dikkatle inceleyin: run() işlevi içinde IP adresini asla değiştirmez. Mantıksal işler arasında geçiş yapar, asla bir işin ortasında değil — kimlik doğrulaması yapılmış bir akış sırasında değişen çıkış IP adresi, oturum ele geçirme gibi görünür ve bu, veri kazıma işleminden daha kötü bir işarettir.
İşler birbirinden bağımsızsa ve öngörülebilir bir döngüden kaçınmak istiyorsanız, rastgele seçim, sırayla dağıtım yöntemine makul bir alternatiftir. Her iki yönteme de eklenmesi gereken bir yaklaşım ise “başarısızlık durumunda rotasyon”dur: Bir proxy blokları geri vermeye başladığında, ona iş vermeye devam etmek yerine onu havuzdan çıkarın.
Çalışmayan bir proxy ile engellenmiş bir isteği birbirinden ayırt etme
requests.exceptions.ProxyError ve ConnectTimeout, bağlantının hiçbir zaman kurulamadığı anlamına gelir — bu proxy’yi havuzdan derhal çıkarın; çünkü aynı çıkış IP’si üzerinden yeniden deneme yapmak, hiçbir fayda sağlamadan sadece zaman aşımını uzatır. 403 hatası veya CAPTCHA sayfası ise farklı bir işarettir: bu, hedefin o IP'nin itibarına ilişkin görüşüdür, arkasındaki modemin arızası değildir ve tek başına, aksi takdirde sağlıklı olan bir bağlantıyı devre dışı bırakmayı haklı çıkarmaz.
429 Hatalarının İşlenmesi: Yeniden Deneme Süresi, Üstel Geri Çekilme ve Jitter
429 kodu, istek hızının yanlış olduğunu belirten bir hatadır. IP adresini değiştirip yeniden istek göndermek, hız sorununu bir kimlik sorunu olarak ele alır; işte bu şekilde, yavaşlatma durumundaki bir istek engelleme durumuna dönüşür. Retry-After kuralına uyun ve bekleme süresini üstel olarak artırın:
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
retry = Retry(
total=5,
backoff_factor=1.5, # 1.5s, 3s, 6s, 12s, 24s
status_forcelist=[429, 500, 502, 503, 504],
respect_retry_after_header=True,
allowed_methods=["GET", "HEAD"],
)
s.mount("https://", HTTPAdapter(max_retries=retry, pool_maxsize=20))
Eşzamanlı işleyiciler çalıştırıyorsanız, üstüne bir miktar dalgalanma ekleyin; aksi takdirde hepsi aynı anda uyanıp yeniden deneme yapacaktır — bu da orijinal trafiğe kıyasla çok daha mekanik görünen, gürültülü bir akın oluşturur. Ayrıca eşzamanlılık, genel olarak değil, hedef ana bilgisayar başına uygulanmalıdır: sekiz etki alanına yayılmış sekiz paralel istek normalken, tek bir etki alanına yönelik sekiz istek bir ani yoğunluktur.
Yeniden denemeler idempotent olmalıdır. `status_forcelist` ile birlikte bir nesne oluşturan bir POST isteği, bu nesneyi sorunsuz bir şekilde birkaç kez oluşturacaktır. Yukarıda belirtildiği gibi `allowed_methods` değerini GET ve HEAD ile sınırlamak, güvenli varsayılan ayardır.
Scrapy ve asyncio: Orta Katman Yazılımı, aiohttp ve Eşzamanlılık Sınırları
Scrapy already ships proxy support. Its built-in HttpProxyMiddleware reads request.meta["proxy"], so setting that key in a spider or a small middleware is enough for a single endpoint. For rotation across a list, scrapy-rotating-proxies adds a pool and its own ban tracking:
ROTATING_PROXY_LIST = [
"http://user:pass@host:10001",
"http://user:pass@host:10002",
]
# or: ROTATING_PROXY_LIST_PATH = "proxies.txt"
DOWNLOADER_MIDDLEWARES = {
"rotating_proxies.middlewares.RotatingProxyMiddleware": 610,
"rotating_proxies.middlewares.BanDetectionMiddleware": 620,
}
CONCURRENT_REQUESTS_PER_DOMAIN = 4
DOWNLOAD_DELAY = 0.5
AUTOTHROTTLE_ENABLED = True
Varsayılan engelleme heuristiği, 200 olmayan bir durum kodunu, boş bir gövdeyi veya bir istisnayı “ölü proxy” olarak değerlendirir; bu yaklaşım oldukça kaba bir yaklaşımdır — bir engellemeye 200 durum koduyla ve bir doğrulama sayfasıyla yanıt veren bir hedef, bu filtreyi kolayca aşacaktır. ROTATING_PROXY_BAN_POLICY'yi, sizi engellediğinde hedefinizin ne yaptığını tanıyan bir sınıfla geçersiz kılın.
Engellenmemek için alttaki iki ayar, ara yazılımdan daha önemlidir. AutoThrottle, gecikmeyi gözlemlenen gecikme süresine göre ayarlar ve etki alanı başına eşzamanlılık sınırı, geniş çaplı bir taramanın tek bir ana bilgisayara yönelik yoğun bir trafiğe dönüşmesini önler.
aiohttp ile proxy, oturum yerine her bir istek düzeyinde çalışır; bu da istek başına rotasyonu oldukça basit hale getirirken, ana bilgisayar başına nazik erişim uygulamasını tamamen sizin sorumluluğunuz altına alır. Veri alma işlemlerinizi, hedef ana bilgisayara göre anahtarlanmış bir semaforla sarın — asyncio, nazik bir taramayı istemediğiniz bir hizmet reddi saldırısına dönüştürmeyi çok kolaylaştırır.
Özel bir Python Veri Toplama Proxy'si edinin
Canlı PXM2 konumları — hedef kitlenizin isteğin hangi ülkeden geldiğini göreceğini seçin ve sınırsız bant genişliği ile rotasyon özelliğine sahip özel bir 4G/5G IP adresi edinin:
Amerika Birleşik Devletleri
Birleşik Krallık
Fransa
Sık Sorulan Sorular
Python requests kütüphanesinde proxy'leri nasıl dönüşümlü olarak kullanabilirim?
Keep a list of endpoints and cycle it with itertools.cycle, assigning one proxy per Session rather than per request — a Session carries the connection pool and cookie jar, so swapping its proxy mid-flight defeats the point of having one. For a single rotating endpoint the rotation happens upstream, and your code only needs to decide when to ask for a new IP.
Python proxy'm neden HTTPS için çalışmıyor?
Neredeyse her zaman bunun nedeni, proxies sözlüğündeki https girdisine https:// şeması verilmiş olmasıdır. Bu şema, proksiye nasıl ulaşılacağını açıklar; hedefin protokolünü değil; ve sıradan bir HTTP proksisi için bu şema yine de http:// olmalıdır. Ardından istemci, bu proksi üzerinden bir CONNECT tüneli açar ve TLS, bu tünelin içinde uçtan uca çalışır.
aiohttp ile proxy'yi nasıl kullanabilirim?
aiohttp bunu her çağrı için ayrı ayrı aldığından, proxy= değerini oturuma değil, tek tek isteklere aktarın. Kimlik bilgileri URL'ye eklenebilir veya proxy_auth olarak geçirilen bir aiohttp.BasicAuth nesnesinde belirtilebilir. Hedef ana bilgisayar başına eşzamanlılık sayısını bir semaforla sınırlayın — asyncio, kibar bir taramayı hız sınırlamasına maruz kalmanıza neden olacak bir ani yoğunluğa dönüştürmeyi son derece kolaylaştırır.
Scrapy'de proxy ayarını nasıl yapabilirim?
Yerleşik HttpProxyMiddleware, request.meta["proxy"] değerini okur; bu nedenle, bir örümcek veya özel bir ara yazılımda bu anahtarı ayarlamak, tek bir uç nokta için yeterlidir. Bir liste üzerinden dönüşümlü kullanım için scrapy-rotating-proxies, ROTATING_PROXY_LIST'e kendi ara yazılımlarını ekler ve hangi uç noktaların engellendiğini takip ederek bunların kullanımını durdurur.
Python’da veri toplama işlemi yaparken 429 hatalarıyla nasıl başa çıkabilirim?
Read the Retry-After header and wait that long. Where the server does not send one, back off exponentially with jitter. urllib3’s Retry does both — set respect_retry_after_header and a backoff_factor, mount it on an HTTPAdapter, and resist the urge to rotate IP and retry immediately: a 429 is a rate problem, and treating it as an identity problem is how a crawl escalates to a hard block.
İlgili Mobil Proxy Kılavuzları
Hedefiniz verilerini JavaScript ile işliyorsa, yukarıdaki HTTP istemcisi yolu ona ulaşamayacaktır — tarayıcı kılavuzu bu durumu ele almaktadır.
Web veri toplama kılavuzları
Temel mobil proxy kılavuzları
Python kazıyıcınızı bir operatörün IP adresine yönlendirin
Sıradan HTTP(S) ve SOCKS5 uç noktalarında özel 4G/5G modemler — satıcı SDK’sı yok, bant genişliği kısıtlaması yok ve kendi kodunuzdan tetiklediğiniz rotasyon.
Python için bir veri toplama proxy'si edinin