Bez KYC — brak dowodu, selfie i dokumentów. Płać w kryptowalutach: BTC, USDT, USDC, ETH, SOL, LTC
Język: Polski
Rozpocznij

Dokumentacja · współbieżność · przepustowość · uprzejmość

Współbieżność i przepustowość przez proxy rezydencjalne

Bramka nalicza opłaty za GB, nie za wątki, więc twoim prawdziwym limitem jest każda docelowa strona. Dobierz współbieżność na podstawie potrzebnej przepustowości, ogranicz ją na hosta i pozwól odpowiedziom wskazać, kiedy zwolnić.

Ostatnia aktualizacja: · 5 min czytania

Szybka odpowiedź

Ile jednoczesnych żądań mogę uruchomić przez proxy rezydencjalne?

Tyle, ile toleruje każda strona docelowa: CrawlRelay nalicza opłaty za ruch residential traffic za GB (0,50 USD/GB od 50 GB), nie za wątki ani połączenia. Dobierz współbieżność zgodnie z prawem Little'a, liczba żądań w locie = strony na sekundę × sekundy na stronę, potem ogranicz ją na hosta, zaczynając od 2 do 4. Zmniejsz, gdy pojawią się odpowiedzi 429 lub 503. Płatność w kryptowalutach, bez KYC.

Współbieżność w skrócie

RozliczeniaZa GB ruchu; wątki i połączenia nie są rozliczane
Reguła dobieraniaLiczba żądań w locie = przepustowość × opóźnienie (prawo Little'a)
Punkt startowy na hosta2–4 równoległe żądania; 1 z opóźnieniem dla małych stron
Sygnały do zwolnienia429, 503, rosnące czasy odpowiedzi, strony z wyzwaniami
Matematyka pasmaStrony na sekundę × bajty na stronę × 3600 = bajty na godzinę
Średni czas odpowiedzi residential proxy0,93 s w sieci proxy, 3,21 s na rzeczywistych celach (Proxyway 2026)

Jak dobrać współbieżność na podstawie potrzebnej przepustowości?

Użyj prawa Little'a: liczba żądań w locie to mnożnik tempa przez czas realizacji każdego żądania. Badanie Proxyway Proxy Market Research 2026 zmierzyło medianę 3,21 sekund na żądanie na rzeczywistych celach przez proxy rezydencjalne, więc planuj 2 do 4 sekund dla prawdziwych stron, a nie tylko ułamka sekundy sieci.

CelCzas na żądanieŻądania w locie
5 stron na sekundę2 s10
20 stron na sekundę2 s40
20 stron na sekundę4 s80
100 stron na sekundę3 s300

Potem rozłóż te żądania na hosty. Czterdzieści żądań w locie przez 200 stron to delikatne obciążenie; czterdzieści żądań na jednej małej stronie to test obciążeniowy, na który nigdy się nie zgodziła.

Ile pasma zużywa taka przepustowość?

Pomnóż strony na sekundę przez bajty na stronę. Przy 20 stronach HTML na sekundę i 50 KB na stronę, crawl zużywa 1 MB na sekundę, co daje 3,6 GB na godzinę i około 86 GB na dzień. Przy 2 MB na wyrenderowaną stronę, ten sam ruch generuje 40 MB na sekundę.

Pomnóż wynik przez cenę za GB w swoim planie, 0,50 USD/GB od 50 GB po CrawlRelay, aby poznać koszt na godzinę. Przewodnik po kalkulatorze pasma podaje typowe wagi stron według typu.

Jakie limity na hosta powinienem zacząć stosować?

CelRównoległe żądania na hostaOpóźnienie między żądaniamiUwagi
Mała strona (blog, lokalny sklep)12–5 sSzanuj Crawl-delay w robots.txt, jeśli występuje
Średnia strona2–40,5–2 sMonitoruj czasy odpowiedzi; zwalniaj, gdy się podwajają
Duża platforma z CDN4–16AutoThrottle lub adaptacyjneZwiększaj tylko jeśli współczynniki 429 i 5xx pozostają stabilne
Publiczne APIUdokumentowany limitJak w dokumentacjiUżywaj klucza API i limitów, które dostawca Ci przydziela

Jak automatycznie dostosować współbieżność?

Stosuj zasadę additive increase i multiplicative decrease, jak w TCP przy przeciążeniach: dodawaj jedno miejsce po serii poprawnych odpowiedzi, dziel limit na pół przy 429 lub 503. Poniższy limiter utrzymuje jeden limit na host, wstrzymuje każde żądanie do tego hosta na Retry-After opóźnienia, wykonuje jedno ponowienie i nigdy nie przekracza ustawionego maksimum. Błędy sieci zwracane są jako wartości, więc jedno przekroczenie czasu nie zatrzyma całej partii.

Python asyncio: adaptacyjny limit z httpx
import asyncio
import random
from urllib.parse import urlsplit

import httpx

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


class AdaptiveLimit:
    """One per host: +1 slot after 20 clean responses, halve on 429/503, pause for Retry-After."""

    def __init__(self, start=2, low=1, high=16):
        self.limit, self.low, self.high = start, low, high
        self.in_flight, self.clean = 0, 0
        self.pause_until = 0.0
        self.cond = asyncio.Condition()

    async def __aenter__(self):
        loop = asyncio.get_running_loop()
        while True:
            async with self.cond:
                await self.cond.wait_for(lambda: self.in_flight < self.limit)
                delay = self.pause_until - loop.time()
                if delay <= 0:
                    self.in_flight += 1
                    return self
            await asyncio.sleep(delay)  # the host asked for a pause: wait outside the lock

    async def __aexit__(self, *exc):
        async with self.cond:
            self.in_flight -= 1
            self.cond.notify_all()

    def record(self, status, retry_after=None):
        if status in (429, 503):
            self.limit, self.clean = max(self.low, self.limit // 2), 0
            wait = int(retry_after) if retry_after and retry_after.isdigit() else 5 + random.random()
            now = asyncio.get_running_loop().time()
            self.pause_until = max(self.pause_until, now + wait)
        elif status < 400:
            self.clean += 1
            if self.clean >= 20 and self.limit < self.high:
                self.limit, self.clean = self.limit + 1, 0


gates = {}


def gate_for(url):
    host = urlsplit(url).hostname
    if host not in gates:
        gates[host] = AdaptiveLimit()
    return gates[host]


async def fetch(client, url, attempts=2):
    gate = gate_for(url)
    status = None
    for _ in range(attempts):
        try:
            async with gate:
                r = await client.get(url)
        except httpx.HTTPError as exc:
            return "error: %s" % type(exc).__name__
        status = r.status_code
        gate.record(status, r.headers.get("Retry-After"))
        if status not in (429, 503):
            break  # the retry, if any, waits for the host's pause in __aenter__
    return status


async def main(urls):
    timeout = httpx.Timeout(30.0, connect=10.0)
    async with httpx.AsyncClient(proxy=PROXY, timeout=timeout) as client:
        print(await asyncio.gather(*(fetch(client, u) for u in urls)))
    print({host: gate.limit for host, gate in gates.items()})


asyncio.run(main(["https://example.com/"] * 10))

Co spowalnia crawl przez proxy oprócz celu?

  • Negocjacje TLS. Nowe połączenie na żądanie, potrzebne dla nowego IP za każdym razem, oznacza handshake z serwerem przy każdej próbie. Utrzymuj sticky session z keep-alive dla wielu stron jednego serwisu, gdy różnorodność IP nie jest ważna.
  • Wolne wyjścia. Proxy rezydencjalne i mobilne proxy 4G to prawdziwe domowe lub komórkowe łącza. Używaj timeoutów i ponawiaj próbę przez nowe połączenie zamiast czekać bez końca.
  • Wąskie targetowanie. Małe miasto lub pojedynczy ASN mają mniej wyjść niż kraj. Celuj wąsko tylko tam, gdzie dane się zmieniają.
  • Renderowanie. Headless browser zużywa znacznie więcej CPU, pamięci i transferu niż klient HTTP. Renderuj tylko strony wymagające JavaScript.
  • DNS. Przy socks5h:// lub porcie HTTP rozstrzyganie DNS odbywa się po stronie proxy; nie potrzebujesz lokalnego cache resolvera dla celów.

Pytania o współbieżność

Czy CrawlRelay ogranicza liczbę wątków lub połączeń?

Plany są rozliczane za GB transferu, nie za wątki, połączenia czy żądania; podane plany nie definiują limitu wątków. Praktyczne limity zależą od tolerancji celu i możliwości Twojego komputera. Jeśli planujesz bardzo duży crawl, skontaktuj się z [email protected] najpierw, abyśmy mogli sprawdzić zasięg twojego targetowania.

Dlaczego crawl zwolnił po dodaniu więcej wątków?

Zazwyczaj dlatego, że cel zaczął throttling: rosną czasy odpowiedzi, pojawiają się kody 429 lub 503, a ponowienia powodują dodatkowe obciążenie. Inny powód to wyczerpanie CPU lub gniazd sieciowych na Twojej maszynie, szczególnie przy headless browserach. Mierz opóźnienia i błędy na host zanim dodasz więcej wątków.

Czy jedno połączenie na żądanie jest wolniejsze niż keep-alive?

Tak, każde żądanie oznacza jeden handshake TCP i TLS, zwykle kilkaset milisekund przez proxy rezydencjalne. To koszt posiadania nowego IP przy każdym żądaniu. Przy wielu stronach tego samego serwisu, gdzie IP nie ma znaczenia, sticky session z keep-alive jest szybsza i oszczędza transfer.

Jak respektować robots.txt crawl-delay w crawlerze współbieżnym?

Parsuj robots.txt raz na host, cachuj do 24 godzin według RFC 9309 i zamień wartość Crawl-delay na minimalną przerwę między żądaniami na hosta przy współbieżności 1. Pythonowe urllib.robotparser udostępnia to przez crawl_delay().

Skaluj na podstawie ceny za GB

0,50 USD/GB od 50 GB do 1 TB, transfer bez daty wygaśnięcia.

Od 0,50 USD/GB · bez KYC

Rozpocznij