Kort antwoord
Hoeveel gelijktijdige verzoeken kan ik via residentiële proxy's uitvoeren?
Zoveel als elke doelsite tolereert: CrawlRelay rekent residentieel verkeer per GB (US$ 0,50/GB vanaf 50 GB) af, niet per thread of verbinding. Bepaal gelijktijdigheid met de wet van Little, verzoeken in uitvoering = pagina's per seconde × seconden per pagina, begrens daarna per host, startend bij 2 tot 4. Verlaag dit bij 429 of 503 reacties. Betaald in crypto, zonder KYC.
Gelijktijdigheid in een oogopslag
| Facturering | Per GB verkeer; threads en verbindingen worden niet in rekening gebracht |
|---|---|
| Regel voor omvang | In uitvoering = doorvoer × latentie (wet van Little) |
| Startpunt per host | 2–4 gelijktijdige verzoeken; 1 met vertraging voor kleine sites |
| Signalen om te vertragen | 429, 503, stijgende responstijden, challenge-pagina's |
| Bandbreedte berekening | Pagina's per seconde × bytes per pagina × 3.600 = bytes per uur |
| Mediane reactietijd residentieel | 0,93 s op het proxy-netwerk, 3,21 s op echte doelen (Proxyway 2026) |
Hoe bepaal ik gelijktijdigheid aan de hand van de benodigde doorvoer?
Gebruik de wet van Little: het aantal verzoeken in uitvoering is gelijk aan het gewenste tempo vermenigvuldigd met de tijd die elk verzoek kost. Proxyway's Proxy Market Research 2026 meet een mediane tijd van 3,21 seconden per verzoek op echte doelen via residentiële proxy's, dus plan met 2 tot 4 seconden voor echte sites, niet met het sub-seconde cijfer van het netwerk alleen.
| Doel | Tijd per verzoek | Verzoeken in uitvoering |
|---|---|---|
| 5 pagina's per seconde | 2 s | 10 |
| 20 pagina's per seconde | 2 s | 40 |
| 20 pagina's per seconde | 4 s | 80 |
| 100 pagina's per seconde | 3 s | 300 |
Verspreid die verzoeken dan over hosts. Veertig verzoeken in uitvoering over 200 sites is rustig; veertig op één kleine site is een load test waar die nooit mee akkoord ging.
Hoeveel bandbreedte verbruikt die doorvoer?
Vermenigvuldig pagina's per seconde met bytes per pagina. Bij 20 HTML-pagina's per seconde en 50 KB per pagina verplaatst de crawl 1 MB per seconde, wat 3,6 GB per uur en ongeveer 86 GB per dag is. Bij 2 MB per gerenderde pagina zou hetzelfde tempo 40 MB per seconde verplaatsen.
Vermenigvuldig het resultaat met de prijs per GB van je abonnement, US$ 0,50/GB vanaf 50 GB tegen CrawlRelay, om de uurtarief te berekenen. De bandbreedte-calculator gids geeft typische paginagroottes per paginatype.
Met welke per-host limieten moet ik beginnen?
| Doel | Gelijktijdige verzoeken per host | Tussenpoos tussen verzoeken | Opmerkingen |
|---|---|---|---|
| Kleine site (blog, lokale winkel) | 1 | 2–5 s | Houd rekening met Crawl-delay in robots.txt indien aanwezig |
| Medium site | 2–4 | 0,5–2 s | Houd responstijden in de gaten; verminder bij verdubbeling |
| Groot platform met CDN | 4–16 | AutoThrottle of adaptief | Verhoog alleen zolang 429- en 5xx-percentages stabiel blijven |
| Publieke API | De gedocumenteerde limiet | Zoals gedocumenteerd | Gebruik de API-sleutel en limieten die de provider biedt |
Hoe pas ik gelijktijdigheid automatisch aan?
Gebruik additieve verhoging en multiplicatieve verlaging, de regel die TCP voor congestie gebruikt: voeg één slot toe na een reeks schone reacties, halveer de limiet bij een 429 of 503. De limiter hieronder houdt per host één limiet bij, pauzeert elke aanvraag naar die host voor de Retry-After vertraging, probeert één keer opnieuw en overschrijdt nooit een ingestelde plafondwaarde. Netwerkfouten worden als waarden teruggegeven, dus één time-out stopt de batch niet.
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))Wat vertraagt een geproxiede crawl behalve de doelwebsite?
- TLS-handshakes. Elke nieuwe verbinding per verzoek, die nodig is voor een nieuwe IP elke keer, voegt een handshake toe met de site. Houd een sticky sessie met keep-alive voor pagina's van één site als IP-diversiteit niet belangrijk is.
- Trage exits. Residentiële en mobiele 4G-proxy's zijn echte thuis- en mobiele verbindingen. Gebruik time-outs en probeer op een nieuwe verbinding opnieuw in plaats van wachten.
- Nauwkeurig targeten. Een kleine stad of een enkele ASN heeft minder exits dan een heel land. Target nauwkeurig alleen waar de data verandert.
- Rendering. Een headless browser verbruikt veel meer CPU, geheugen en verkeer per pagina dan een HTTP-client. Render alleen pagina's die JavaScript nodig hebben.
- DNS. Bij gebruik van
socks5h://of de HTTP-poort doet de DNS-resolutie plaats bij de exit; je hebt geen lokale resolvercache nodig voor target-hosts.
Vragen over gelijktijdigheid
Beperkt CrawlRelay het aantal threads of verbindingen?
Plannen worden gefactureerd per GB traffic, niet per thread, verbinding of verzoek, en de gepubliceerde plannen stellen geen limiet aan het aantal threads. De praktische limieten zijn de tolerantie van elk doel en je eigen machine. Als je een heel grote crawl plant, schrijf dan eerst naar [email protected] zodat we de dekking voor je targeting kunnen controleren.
Waarom werd mijn crawl trager toen ik meer threads toevoegde?
Meestal omdat de doelwebsite je begon te throttlen: responstijden stijgen, 429 of 503 antwoorden verschijnen, en herhalingen zorgen voor extra belasting. De andere veelvoorkomende oorzaak is dat je eigen machine door zijn CPU of sockets heen raakt, vooral bij headless browsers. Meet latentie en foutpercentages per host voordat je threads toevoegt.
Is één verbinding per verzoek trager dan keep-alive?
Ja, door één TCP- en TLS-handshake per verzoek, meestal enkele honderden milliseconden via een residentiële exit. Dat is de prijs voor een nieuw IP bij elk verzoek. Voor veel pagina's van één site waarbij het IP niet uitmaakt, is een sticky sessie met keep-alive sneller en gebruikt minder verkeer.
Hoe respecteer ik robots.txt crawl-delay in een concurrerende crawler?
Parse robots.txt één keer per host, cache het tot 24 uur zoals RFC 9309 aanbeveelt, en zet een Crawl-delay waarde om in een minimale pauze per host tussen aanvragen bij een gelijktijdigheid van 1. Pythons urllib.robotparser maakt dit toegankelijk via crawl_delay().
Schaalbaar met per-GB prijsstelling
US$ 0,50/GB van 50 GB tot 1 TB, verkeer dat nooit verloopt.