Kort antwoord
Hoe werken sticky sessions en IP-rotatie op een residentiële proxy?
Op CrawlRelay krijgt een gebruikersnaam zonder sessie-ID bij elke nieuwe TCP-verbinding een IP uit de pool, meestal een ander IP, en -session-<id>-ttl-<minutes> houdt één IP voor die ID vast voor tot 30 minuten, hoewel het IP ook vroeger kan veranderen. Rotatie volgt verbindingen, niet HTTP-verzoeken, dus keep-alive bepaalt wanneer je IP echt wisselt. Residentieel verkeer kost US$ 0,50/GB vanaf 50 GB. Betaald in crypto, zonder KYC.
Sessie regels in één oogopslag
| Rotatie-eenheid | Een IP uit de pool per nieuwe TCP-verbinding, meestal een ander IP |
|---|---|
| Sticky session | -session-<id>-ttl-<minutes> toegevoegd aan de gebruikersnaam |
| Sessieduur | tot 30 minuten |
| Sessie-ID | 1–32 letters of cijfers; één ID per flow |
| Wat een sessie vroegtijdig beëindigt | Het residentiële apparaat erachter dat offline gaat |
| Gedeelde ID's | Klanten die dezelfde ID gebruiken, delen dezelfde exit |
| Kosten | Geen: sessies en rotatie zijn inbegrepen in de prijs per GB |
Wat gebeurt er bij de gateway wanneer ik een sessie-ID verzend?
De gateway leest de gebruikersnaam bij elke nieuwe verbinding. Zonder een sessie-onderdeel kiest hij een residentiële proxy als exit die bij je targeting past, alleen voor die verbinding. Met een sessie-onderdeel houdt hij dezelfde exit aan voor die ID tot de TTL die je instelt.
Een sticky IP is een echte huisverbinding, dus die kan verdwijnen vóór het einde van de TTL: het apparaat wordt uitgeschakeld, verliest Wi-Fi of wisselt netwerk. Lange flows moeten dit overleven door op checkpoints het exit-IP te controleren en opnieuw te starten vanaf een checkpoint in plaats van de hele klus te laten mislukken.
Hoe hergebruikt elke library verbindingen?
Als een library een verbinding openhoudt, deelt elk verzoek daarop één exit. Zo krijg je het gewenste gedrag bewust.
| Library | Standaard | Nieuw IP per verzoek | Eén IP voor een flow |
|---|---|---|---|
| Python requests | Session houdt verbindingen open | Header Connection: close, of een nieuwe Session per verzoek | Eén Session met een sessie-ID in de gebruikersnaam |
| httpx | Client poolt verbindingen | httpx.Limits(max_keepalive_connections=0) | Één client per sessie-ID |
| aiohttp | TCPConnector poolt verbindingen | TCPConnector(force_close=True) | Sessie-ID in de proxy-URL gebruikersnaam |
| Scrapy | Pools per proxy-inloggegevens en host | meta={"proxy_session": "new"} met onze middleware | Een vaste proxy_session voor de flow |
| Playwright / Puppeteer | Chrome poolt per context | Nieuwe context per pagina | Eén context per sessie-ID |
| Node.js undici, axios, got | Agents houden sockets open | Nieuwe agent per verzoek, of keep-alive uit | Één agent per sessie-ID |
| curl | Eén verbinding per commando | Al zo | Zelfde sessie-ID in elk commando |
Welke sessiestrategie past bij welke scrapingklus?
| Klus | Strategie | Aangeraden TTL |
|---|---|---|
| Onafhankelijke product-, artikel- of lijstpagina's | Draaien: geen sessie-ID | — |
| Paginering waarvan de volgende pagina afhankelijk is van een cookie of cursor | Één sticky sessie per vermelding | 10–30 min |
| Zoeken, dan resultaten, dan detailpagina's | Één sticky sessie per zoekopdracht | 10–20 min |
| Headless browser die meerdere pagina's van één site rendert | Één sticky sessie per browsercontext | De levensduur van de context, tot 30 min |
| Controleren wat een pagina toont in meerdere steden | Één korte sessie per stadcontrole | 5 min |
| Dezelfde pagina elk uur opnieuw controleren | Draaien | — |
Hoe beheer ik een pool van sticky sessies in Python?
Een kleine pool verdeelt de last over enkele stabiele uitgangen en zet elke uitgang na een vastgesteld aantal verzoeken of bij een teken dat de uitgang faalt, zoals 502 of 503, uit de roulatie. Let op wat het juist niet doet: het wisselt geen IP's om langs een 403 of 429 te komen. Die betekenen dat de site wil dat je vertraagt, dus verhoogt de pool die aan jouw code.
import random
import uuid
import requests
GATEWAY = "gw.crawlrelay.com:7777"
BASE_USER, PASSWORD = "USERNAME-country-us", "PASSWORD"
class SlowDown(Exception):
"""The target asked us to slow down (403 or 429): back off, do not rotate."""
class StickySession:
def __init__(self, ttl=15, max_requests=50):
self.id = uuid.uuid4().hex[:10]
self.max_requests, self.used = max_requests, 0
user = "%s-session-%s-ttl-%d" % (BASE_USER, self.id, ttl)
proxy = "http://%s:%s@%s" % (user, PASSWORD, GATEWAY)
self.http = requests.Session()
self.http.proxies = {"http": proxy, "https": proxy}
class SessionPool:
EXIT_PROBLEMS = {502, 503, 504}
def __init__(self, size=5, **options):
self.options = options
self.sessions = [StickySession(**options) for _ in range(size)]
def _replace(self, i):
self.sessions[i].http.close()
self.sessions[i] = StickySession(**self.options)
def get(self, url, **kwargs):
i = random.randrange(len(self.sessions))
s = self.sessions[i]
s.used += 1
try:
r = s.http.get(url, timeout=(10, 30), **kwargs)
except requests.exceptions.RequestException:
self._replace(i) # dropped exit or timeout: start a fresh session
raise
if r.status_code in (403, 429):
raise SlowDown("%s returned %d" % (url, r.status_code))
if r.status_code in self.EXIT_PROBLEMS or s.used >= s.max_requests:
self._replace(i)
return r
pool = SessionPool(size=5, ttl=15, max_requests=50)
print(pool.get("https://api.ipify.org").text)Hoe weet ik dat een sticky IP is veranderd?
Vraag het. Doe een IP-echo aanvraag, zoals https://api.ipify.org, via dezelfde sessie aan het begin van een flow en bij elk controlepunt, en vergelijk de antwoorden. Een verandering betekent dat de exit achter de sessie veranderde: start de flow opnieuw op vanaf het laatste controlepunt of open een nieuwe sessie. Log dit met het sessie-ID zodat je IP-wijzigingen kunt onderscheiden van sitegedrag bij het debuggen.
Welke sessiefouten kosten het meest?
- Roteren bij elk verzoek van een multi-step flow. De site ziet een winkelwagen, cursor of zoektoken tussen landen springen en reset het.
- Één sessie-ID voor elke worker. Een sessie is bedoeld voor één flow; geef elke worker en flow een eigen ID.
- Sessies veel langer dan de taak. Een TTL van 30 minuten voor een flow van 2 minuten houdt een IP onnodig bezet en maakt logs moeilijker leesbaar.
- Een 429 behandelen als een IP-probleem. Een nieuw IP verandert de regels van de site niet; vertragen wel. Zie 429 Too Many Requests.
- Aannemen van rotatie per verzoek. Keep-alive behoudt de uitgang; zie de tabel hierboven voor je bibliotheek.
Sessies en rotatie: vragen
Hoe lang duurt een sticky sessie?
Sticky sessions houden hetzelfde IP voor de door jou ingestelde tijd (ttl, in minuten), tot 30 minuten. Het IP kan eerder veranderen, bijvoorbeeld als het residentiële apparaat offline gaat. Kies een TTL iets langer dan de flow die het bedient en controleer de exit bij controlepunten.
Is een sticky sessie duurder dan rotatie?
Nee. CrawlRelay rekent verkeer per GB af, en sessies, rotatie en targeting zijn inbegrepen in die prijs. Een sticky sessie kan zelfs verkeer besparen, omdat één keep-alive verbinding per verzoek een nieuwe TLS-handshake voorkomt.
Is rotatie bij elk verzoek beter voor scraping?
Voor onafhankelijke pagina's verspreidt rotatie de last en voorkom je dat je urenlang met één IP dezelfde site bezoekt. Voor alles met status, zoals paginering gekoppeld aan een cookie, breekt het de flow. De meeste crawls combineren beide: roteer tussen items, blijf sticky binnen een flow.
Kan ik het exacte IP kiezen dat ik krijg?
Nee. Een residentiële gateway wijst exits toe uit een pool die voortdurend verandert, passend bij de targeting in je gebruikersnaam. Je kiest het land, stad, US staat, postcode of ASN, en je kunt een IP vasthouden met een sessie; je kunt geen specifiek adres reserveren.
Rotatie en sessies in elk abonnement
US$ 1,50 voor 1 GB, US$ 0,50/GB vanaf 50 GB.