Tanpa KYC — tanpa ID, tanpa selfie, tanpa dokumen. Bayar dengan crypto: BTC, USDT, USDC, ETH, SOL, LTC
Bahasa: Bahasa Indonesia
Mulai sekarang

Dokumentasi · Python 3.9+ · requests · httpx · aiohttp

Proxy residensial berputar di Python: requests, httpx dan aiohttp

Pola produksi, bukan satu baris: retries yang menghormati Retry-After, IP baru per permintaan atau satu IP per alur, concurrency per-host di asyncio, dan byte yang benar-benar dipakai tiap halaman.

Terakhir diperbarui: · 6 baca dalam menit

Jawaban cepat

Bagaimana cara menggunakan proxy residensial berputar di Python?

Gunakan http://USERNAME:[email protected]:7777 sebagai proxy untuk http dan https di requests, sebagai proxy= di httpx 0.26+, atau sebagai proxy= per permintaan di aiohttp. CrawlRelay proxy residensial berputar di setiap koneksi baru dan tetap sticky dengan -session-<id> pada username. Biayanya US$1,50 per 1 GB dan US$0,50/GB dari 50 GB. Dibayar pakai crypto, tanpa KYC.

Setup Python sekilas

requestsproxies={"http": url, "https": url}; retries lewat urllib3 Retry
httpxhttpx.Client(proxy=url); argumen proxies= lama dihapus di httpx 0.28
aiohttpsession.get(url, proxy="http://USER:PASS@host:port"), kredensial di URL proxy
SOCKS5pip install "requests[socks]" atau httpx[socks], lalu socks5h:// di port 7778
IP baru per permintaanNonaktifkan keep-alive: Connection: close, max_keepalive_connections=0 atau force_close=True
IP sama untuk satu alur-session-<id>-ttl-<minutes> di username, hingga 30 menit
Skema URL proxySelalu http:// untuk port HTTP, bahkan untuk website HTTPS

Bagaimana cara menggunakan proxy dengan requests, dengan retries yang menghormati Retry-After?

Pasang sebuah HTTPAdapter dengan urllib3's Retry pada Session. Ini mengulang jika ada kesalahan koneksi dan status yang Anda daftar, menunggu dengan backoff eksponensial, dan menghormati header Retry-After yang dikirim situs pada 429 dan 503. Set trust_env = False supaya variabel HTTPS_PROXY sisa tidak menimpa proxy Anda.

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)

Bagaimana cara membangun URL proxy yang ditargetkan dengan aman?

Buat username dalam satu fungsi dan validasi. Salah ketik kode negara atau karakter yang tidak terencode di password menghasilkan 407 yang tampak seperti masalah kredensial. Bantuan di bawah menjaga urutan yang didokumentasikan (USERNAME-country-{cc}-state-{state}-city-{city}-zip-{zip}-asn-{asn}-session-{id}-ttl-{minutes}), menolak kunci tidak dikenal dan melakukan URL-encode pada kedua kredensial.

Pembuat username dan URL proxy
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"))

Bagaimana cara mendapatkan IP baru di setiap permintaan dengan httpx?

Matikan keep-alive. httpx mengelola koneksi secara default, dan koneksi yang dipakai ulang mempertahankan IP keluarannya. Dengan max_keepalive_connections=0, tiap permintaan membuka koneksi baru ke gateway dan biasanya keluar lewat proxy residensial berbeda. num_bytes_downloaded memberikan byte yang diterima di jaringan, yang paling mendekati bagaimana biaya trafik dihitung.

httpx: client berputar
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")

Bagaimana cara scrape secara konkuren dengan asyncio tanpa membebani satu situs?

Batasi concurrency per host, bukan hanya secara global. Batas global 50 membiarkan semua 50 permintaan menarget situs yang sama saat daftar URL diurutkan per domain. Semaphore per hostname menjaga tiap situs tetap sopan sementara crawling tetap cepat. Mulai dari 2 sampai 4 per host dan baca panduan concurrency sebelum menaikkannya.

httpx.AsyncClient dengan semaphore per host
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/"]))

Bagaimana cara menggunakan proxy dengan aiohttp?

Lewatkan gateway sebagai proxy= setiap permintaan, dengan kredensial di URL proxy. Ini bekerja di setiap rilis aiohttp 3.x tanpa peringatan; BasicAuth dan parameter proxy_auth= sudah deprecated sejak aiohttp 3.14 dan akan dihapus di versi 4.0. TCPConnector(force_close=True) menutup setiap koneksi setelah responnya, sehingga tiap permintaan biasanya mendapat exit IP baru. Tanpa ini, aiohttp memakai ulang koneksi dan IP tetap sama selama beberapa waktu.

aiohttp dengan kredensial di URL proxy
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())

Bagaimana cara mempertahankan satu IP untuk alur multi-langkah?

Buat satu session ID per alur dan masukkan ke username dengan TTL lebih lama dari alur. Keep-alive baik digunakan di sini: Anda ingin exit yang sama. Jika perangkat residensial di balik sesi offline, IP bisa berubah sebelum TTL habis, jadi buat alurnya bisa diulang dari checkpoint terakhir.

Sesi sticky dengan requests
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")

Berapa banyak trafik yang digunakan scraper Python per halaman?

Ukur di 100 halaman nyata sebelum beli volume. Catat num_bytes_downloaded di httpx, atau panjang body terkompresi di middleware Anda sendiri, lalu kalikan dengan jumlah halaman. Permintaan hanya HTML biasanya menghabiskan puluhan kilobyte per halaman; panduan bandwidth memberikan angka dan biaya per 1.000 halaman dengan harga CrawlRelay.

Tiga kebiasaan yang mengurangi trafik tanpa mengubah hasil:

  • Kirim Accept-Encoding: gzip, br (httpx dan requests kirim gzip secara default) supaya halaman dikirim terkompresi.
  • Ambil endpoint JSON yang dimuat halaman, saat situs mendokumentasikan atau mengizinkannya, daripada HTML lengkap.
  • Lewati halaman yang tidak berubah dengan If-None-Match atau If-Modified-Since: 304 Not Modified berbiaya beberapa ratus byte.

Python dan proxy: pertanyaan

requests, httpx atau aiohttp: mana yang harus saya gunakan untuk scraping?

Gunakan requests untuk skrip sederhana dan crawl kecil. Gunakan httpx ketika Anda ingin API yang sama dalam kode sinkron dan asinkron, serta HTTP/2 melalui httpx[http2]. Gunakan aiohttp untuk konkurensi sangat tinggi dengan asyncio murni. Untuk crawl dengan penjadwalan, deduplikasi, dan pipeline, gunakan Scrapy daripada menulis bagian-bagian itu sendiri.

Mengapa saya mendapatkan SSL: WRONG_VERSION_NUMBER dengan proxy saya di Python?

Anda mungkin menulis https:// di depan alamat proxy. Port gateway 7777 menggunakan HTTP biasa dan membuka koneksi CONNECT untuk situs HTTPS, jadi URL proxy harus dimulai dengan http:// pada kunci http dan https. Lihat halaman error.

Bagaimana cara menggunakan proxy SOCKS5 di Python?

Instal tambahan (pip install "requests[socks]" atau pip install "httpx[socks]"), lalu gunakan socks5h://USERNAME:[email protected]:7778. h mengirim hostname ke proxy, jadi DNS diresolusikan di exit dan Anda melihat jawaban regional yang sama seperti pengunjung lokal.

Mengapa proxy rotasi saya mengembalikan IP yang sama dua kali?

Klien Anda menggunakan kembali koneksi keep-alive, dan rotasi terjadi per koneksi baru. Kirim Connection: close pada requests, atur max_keepalive_connections=0 di httpx, atau gunakan force_close=True di aiohttp. Periksa juga bahwa username tidak memiliki bagian session-, yang sengaja mempertahankan satu IP.

Bagaimana cara mengatur timeout untuk permintaan melalui proxy?

Atur secara eksplisit: requests tidak memiliki timeout secara default. Timeout koneksi sekitar 10 detik dan timeout baca 30 detik cocok untuk halaman HTML; exit seluler dan target lambat memerlukan 45 hingga 60 detik. Coba ulangi timeout sekali pada koneksi baru daripada menunggu lebih lama. Lihat timeout baca.

Bisakah saya menggunakan proxy ini di Jupyter atau dengan pandas?

Ya. Apa pun yang menggunakan requests atau httpx di bawahnya menggunakan pengaturan proxy yang sama. Untuk pandas.read_html atau read_csv pada URL, unduh konten dengan panggilan requests yang melalui proxy dulu, lalu berikan teks atau byte ke pandas.

Jalankan scraper Python Anda melalui IP residensial

US$1,50 untuk 1 GB, US$0,50/GB dari 50 GB.

Dari US$0,50/GB · tanpa KYC

Mulai sekarang