KYC olmadan — kimlik, selfie veya belge istemez. Kripto ile ödeyin: BTC, USDT, USDC, ETH, SOL, LTC
Dil: Türkçe
Başlayın

Belgeler · Python 3.9+ · requests · httpx · aiohttp

Python'da dönen konut proxyler: requests, httpx ve aiohttp

Üretim desenleri, tek satırlık değil: Retry-After'a saygı duyan yeniden denemeler, isteğe özel yeni IP ya da akış başına bir IP, asyncio'da host başına eşzamanlılık ve her sayfanın gerçek byte maliyeti.

Son güncelleme: · 6 dk okuma

Hızlı cevap

Python'da dönen konut proxyleri nasıl kullanırım?

Hem requests'te http hem de https için proxy olarak http://USERNAME:[email protected]:7777 geçin, httpx 0.26+'da proxy= olarak veya aiohttp'da isteğe özel proxy= olarak kullanın. CrawlRelay konut proxyleri her yeni bağlantıda döner ve kullanıcı adında -session-<id> ile yapışkan kalır. 1 GB için $1,50 ve 50 GB’dan itibaren $0,50/GB maliyetlidir. KYC olmadan, kripto ile ödenir.

Python kurulumu kısa bakış

requestsproxies={"http": url, "https": url}; urllib3 üzerinden yeniden denemeler Retry
httpxhttpx.Client(proxy=url); eski proxies= argümanı httpx 0.28'de kaldırıldı
aiohttpsession.get(url, proxy="http://USER:PASS@host:port"), proxy URL'sinde kimlik bilgileri
SOCKS5pip install "requests[socks]" veya httpx[socks], ardından socks5h://, port 7778
İstek başına yeni IPKeep-alive devre dışı bırak: Connection: close, max_keepalive_connections=0 veya force_close=True
Aynı akış için aynı IPKullanıcı adında -session-<id>-ttl-<minutes>, 30 dakikaya kadar
Proxy URL şemasıHTTP portu için her zaman http:// kullanın, HTTPS sitelerde bile

Retry-After'a uyan yeniden denemelerle requests ile proxy nasıl kullanılır?

Bir HTTPAdapter'ı urllib3'ün Retry üzerineSession olarak kurun. Bağlantı hatalarını ve sizin listelediğiniz statü kodlarını tekrar dener, üstel geri çekilme ile bekler ve sitelerin 429 ve 503 ile gönderdikleri Retry-After başlığını dikkate alır. Proxy’nizi geçersiz kılabilecek kalmış HTTPS_PROXY değişkenini önlemek için trust_env = False ayarlayın.

requests + urllib3 Retry
import os

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

USER = os.environ.get("CRAWLRELAY_USER", "USERNAME-country-us")
PASSWORD = os.environ.get("CRAWLRELAY_PASSWORD", "PASSWORD")
PROXY = "http://%s:%[email protected]:7777" % (USER, PASSWORD)

retry = Retry(
    total=4,
    connect=2,
    backoff_factor=1.0,  # waits of 0 s, 2 s, 4 s, 8 s (Retry-After wins on 429/503)
    status_forcelist=(429, 502, 503, 504),
    allowed_methods=frozenset({"GET", "HEAD"}),
    respect_retry_after_header=True,
)

session = requests.Session()
session.trust_env = False  # ignore HTTP(S)_PROXY from the environment
session.mount("http://", HTTPAdapter(max_retries=retry))
session.mount("https://", HTTPAdapter(max_retries=retry))
session.proxies = {"http": PROXY, "https": PROXY}
session.headers["User-Agent"] = "ExampleCrawler/1.0 (+https://example.com/crawler-info)"
session.headers["Connection"] = "close"  # new connection per request, so usually a new exit IP

r = session.get("https://api.ipify.org", timeout=(10, 30))
print(r.status_code, r.text)

Hedefe yönelik proxy URL’leri nasıl güvenli oluştururum?

Kullanıcı adını tek bir fonksiyonda oluşturup doğrulayın. Ülke kodunda yazım hatası veya şifrede kodlanmamış karakter 407](/docs/errors/407-proxy-authentication-required/) hatası verir ve bu kimlik bilgisi problemi gibi görünür. Aşağıdaki yardımcı, belgelenmiş sırayı (USERNAME-country-{cc}-state-{state}-city-{city}-zip-{zip}-asn-{asn}-session-{id}-ttl-{minutes}) korur, bilinmeyen anahtarları reddeder ve her iki kimliği URL'e uygun şekilde kodlar.

Kullanıcı adı oluşturucu ve proxy URL
import re
from urllib.parse import quote

ORDER = ("country", "state", "city", "zip", "asn", "session", "ttl")
VALUE = re.compile(r"^[a-z0-9_]+$")


def build_username(base, **params):
    """build_username("USERNAME", country="us", city="new_york", session="job1", ttl=30)"""
    parts = [base]
    for key in ORDER:
        value = params.pop(key, None)
        if value is None:
            continue
        value = str(value).lower()
        if not VALUE.match(value):
            raise ValueError("bad value for %s: %r" % (key, value))
        if key == "ttl" and not 1 <= int(value) <= 30:
            raise ValueError("ttl must be 1 to 30 minutes")
        parts.append("%s-%s" % (key, value))
    if params:
        raise ValueError("unknown parameters: %s" % ", ".join(sorted(params)))
    return "-".join(parts)


def proxy_url(username, password, socks=False):
    scheme, port = ("socks5h", 7778) if socks else ("http", 7777)
    return "%s://%s:%[email protected]:%d" % (
        scheme, quote(username, safe=""), quote(password, safe=""), port)


print(proxy_url(build_username("USERNAME", country="us", state="ny", city="new_york", session="job1", ttl=20), "p@ss:word"))

httpx ile her istekte nasıl yeni IP alırım?

Keep-alive kapatın. httpx varsayılan olarak bağlantıları havuzlar ve tekrar kullanılan bağlantı çıkış IP’sini korur. max_keepalive_connections=0 ile her istek gateway’e yeni bağlantı açar ve genellikle farklı bir konut proxy IP’den çıkar. num_bytes_downloaded, trafikteki byte'ları verir, ki bu da trafik faturalamasına en yakın değerdir.

httpx: dönen istemci
import httpx

PROXY = "http://USERNAME-country-gb:[email protected]:7777"

# No keep-alive: every request opens a new connection, so it usually gets a new exit IP
with httpx.Client(
    proxy=PROXY,
    timeout=httpx.Timeout(30.0, connect=10.0),
    limits=httpx.Limits(max_keepalive_connections=0),
    follow_redirects=True,
) as client:
    for _ in range(3):
        r = client.get("https://api.ipify.org")
        print(r.text, r.num_bytes_downloaded, "bytes on the wire")

asyncio ile aynı anda nasıl kazıma yaparım ama bir siteyi aşırı yüklemem?

Eşzamanlılığı sadece genel değil, host başına sınırla. Global 50 limiti URL listeniz alan adına göre sıralandığında tüm 50 istek aynı siteye gider. Her host için semafor, her siteyi nazikçe tutar, tüm tarama hızlı kalır. Host başına 2-4 arası başla, artırmadan önce eşzamanlılık rehberini oku.

Host başına semafor ile httpx.AsyncClient
import asyncio
from collections import defaultdict
from urllib.parse import urlsplit

import httpx

PROXY = "http://USERNAME-country-us:[email protected]:7777"
PER_HOST = 4  # parallel requests per target host
host_slots = defaultdict(lambda: asyncio.Semaphore(PER_HOST))


async def fetch(client, url):
    async with host_slots[urlsplit(url).hostname]:
        try:
            r = await client.get(url)
            return url, r.status_code, r.num_bytes_downloaded
        except httpx.HTTPError as exc:
            return url, type(exc).__name__, 0


async def main(urls):
    limits = httpx.Limits(max_connections=50, max_keepalive_connections=0)
    timeout = httpx.Timeout(30.0, connect=10.0)
    async with httpx.AsyncClient(proxy=PROXY, limits=limits, timeout=timeout) as client:
        for result in await asyncio.gather(*(fetch(client, u) for u in urls)):
            print(*result)


asyncio.run(main(["https://example.com/", "https://example.org/", "https://example.net/"]))

aiohttp ile proxy nasıl kullanılır?

Gateway'i her istekte proxy= olarak, kimlik bilgilerini proxy URL'sinde geçin. Bu, uyarısız tüm aiohttp 3.x sürümlerinde çalışır; BasicAuth ve proxy_auth= parametreleri aiohttp 3.14’ten beri kaldırılmıştır ve 4.0’da tamamen kaldırılacak. TCPConnector(force_close=True) her yanıt sonrası bağlantıyı kapatır, böylece genellikle her istek yeni bir çıkış alır. Yoksa aiohttp bağlantıları tekrar kullanır ve IP bir süre aynı kalır.

Kimlik bilgileri proxy URL’sinde olan aiohttp
import asyncio

import aiohttp

# Credentials go in the proxy URL; percent-encode a password that contains @ or :
PROXY = "http://USERNAME-country-fr:[email protected]:7777"


async def main():
    # force_close=True: one connection per request, so each request usually gets a new exit IP
    connector = aiohttp.TCPConnector(limit=20, force_close=True)
    timeout = aiohttp.ClientTimeout(total=60, sock_connect=10)
    async with aiohttp.ClientSession(connector=connector, timeout=timeout) as session:
        for _ in range(3):
            async with session.get("https://api.ipify.org", proxy=PROXY) as resp:
                print(resp.status, await resp.text())


asyncio.run(main())

Çok adımlı bir akışta tek IP nasıl tutulur?

Her akış için bir oturum ID’si oluştur ve TTL’si akıştan uzun olacak şekilde kullanıcı adına koy. Keep-alive doğru, çünkü aynı çıkışı istiyorsun. Eğer konut cihaz arka planda çevrimdışıysa IP TTL bitmeden değişebilir, bu yüzden akışı son kontrol noktasından yeniden başlatılabilir yap.

requests ile yapışkan oturum
import uuid

import requests

session_id = uuid.uuid4().hex[:10]  # one ID per flow, lowercase letters and digits
user = "USERNAME-country-us-state-ca-session-%s-ttl-20" % session_id
proxy = "http://%s:[email protected]:7777" % user

with requests.Session() as s:
    s.proxies = {"http": proxy, "https": proxy}
    first = s.get("https://api.ipify.org", timeout=(10, 30)).text
    second = s.get("https://api.ipify.org", timeout=(10, 30)).text
    print(first, second, "same exit" if first == second else "exit changed")

Python kazıyıcı sayfa başına ne kadar trafik kullanır?

Hacim almadan önce 100 gerçek sayfada ölçün. httpx’de num_bytes_downloaded’yi, kendi ara katmanınızda sıkıştırılmış gövdenin uzunluğunu kaydedin ve sayfa sayınızla çarpın. Sadece HTML istekleri genellikle sayfa başına onlarca kilobayt maliyetlidir; bant genişliği rehberi rakamları ve sayfa başına 1.000 için maliyeti CrawlRelay fiyatlarıyla verir.

Üç alışkanlık trafiği azaltır, sonuçları değiştirmeden:

  • Accept-Encoding: gzip, br gönderin (httpx ve requests varsayılan olarak gzip gönderir) böylece sayfalar sıkıştırılmış gider.
  • Site izin veriyor ve belgeliyorsa, tam HTML yerine sayfanın yüklediği JSON uç noktasını alın.
  • Değişmeyen sayfaları If-None-Match veya If-Modified-Since ile atlayın: 304 Not Modified sadece birkaç yüz byte tutar.

Python ve proxyler: sorular

requests, httpx veya aiohttp: hangisini scraping için kullanmalıyım?

Basit betikler ve küçük taramalar için requests kullanın. Senkron ve asenkron kodda aynı API’yi ve HTTP/2 desteğini httpx[http2] üzerinden kullanmak isterseniz httpx tercih edin. Çok yüksek eşzamanlılık için saf asyncio’da aiohttp kullanın. Zamanlama, tekrarsızlaştırma ve boru hatları içeren bir tarama için, bu parçaları kendiniz yazmak yerine Scrapy kullanın.

Python’da proxy ile neden SSL: WRONG_VERSION_NUMBER hatası alıyorum?

Muhtemelen proxy adresinin önüne https:// yazdınız. Ağ geçidinin 7777 portu sade HTTP konuşur ve HTTPS siteleri için CONNECT tüneli açar; bu yüzden proxy URL’si http ve https anahtarlarında http:// ile başlamalıdır. Detaylar için hata sayfasına bakın.

Python’da SOCKS5 proxyleri nasıl kullanırım?

Ek modülü yükleyin (pip install "requests[socks]" veya pip install "httpx[socks]"), sonra socks5h://USERNAME:[email protected]:7778 kullanın. h, ana makine isimlerini proxy’e gönderir; böylece DNS çıkışta çözülür ve yerel ziyaretçilerle aynı bölgesel yanıtları görürsünüz.

Döner proxy neden aynı IP’yi iki kez döndürüyor?

İstemciniz tutulan bağlantıyı yeniden kullandı, oysa rotasyon her yeni bağlantıda gerçekleşir. requests’de Connection: close gönderin, httpx’de max_keepalive_connections=0 ayarlayın veya aiohttp’da force_close=True kullanın. Ayrıca kullanıcı adında session- kısmı olmadığından emin olun; aksi halde bir IP kasıtlı tutulur.

Proxyli istekler için zaman aşımını nasıl ayarlarım?

Açıkça belirtin: requests’e varsayılan zaman aşımı yoktur. HTML sayfalar için yaklaşık 10 saniye bağlantı ve 30 saniye okuma zaman aşımı uygundur; mobil çıkışlar ve yavaş hedefler için 45 ila 60 saniye gerekir. Daha uzun beklemek yerine, zaman aşımı durumunda yeni bağlantı ile bir kere yeniden deneyin. okuma zaman aşımı için bakın.

Bu proxyleri Jupyter veya pandas ile kullanabilir miyim?

Evet. requests veya httpx kullanan her şey aynı proxy ayarlarını alır. URL’de pandas.read_html veya read_csv var ise, önce proxyli requests çağrısı ile içeriği indirin, sonra metin ya da byte’ları pandas’a iletin.

Python scraper’ınızı konut IP adreslerinden çalıştırın

$1,50 için 1 GB, $0,50/GB 50 GB'ten.

$0,50/GB · KYC olmadan

Başlayın