Je Scrapy-spider vliegt moeiteloos door 100 testpagina’s heen en klapt daarna om bij 10.000 pagina’s. Dat is meestal geen scraping-bug, maar een netwerkprobleem dat zich voordoet als een scraping-bug. De standaardoplossing waar iedereen meteen naar grijpt is een proxy, en zo’n proxy in request.meta zetten kost je ongeveer dertig seconden.
Alleen: die dertig seconden zijn precies waar veel basisgidsen ophouden. Ze laten meta={"proxy": "http://IP:PORT"} zien, misschien nog een middleware-class, en noemen het dan klaar. Wat vaak ontbreekt, is wat er gebeurt als die proxy halverwege de crawl uitvalt, hoe inloggegevens in Git-geschiedenis blijven hangen, of waarom een retry zomaar opnieuw dezelfde mislukte proxy kan gebruiken. Dáár gaat deze gids over: fail-closed configuratie, geheimenbeheer, bewuste proxykeuze bij retries, protocolbeperkingen en meetbare kostenafwegingen.
Wat is een proxy middleware in Scrapy?
Een proxy middleware is code die in Scrapy’s downloader-pipeline zit en bepaalt via welk IP-adres een request lijkt te komen voordat het de deur uitgaat. Scrapy levert standaard al HttpProxyMiddleware mee, die een proxy-sleutel uit request.meta leest, waar nodig proxy-authenticatie toevoegt en de request doorgeeft aan de download handler die de verbinding echt opent. Aangepaste proxy middleware vervangt dat transportstapje niet — het is een selector die vóór de ingebouwde machine beslist welke proxy gebruikt moet worden. Dat onderscheid is belangrijker dan het misschien klinkt, en het verklaart een groot deel van de “mijn custom middleware doet niks”-meldingen.
Waarom proxies belangrijk zijn voor productie-Scrapy-projecten
Een proxy verandert de netwerkroute en het zichtbare bron-IP. Dat kan helpen bij legitieme geo-specifieke tests, geautoriseerde verkeersverdeling en het isoleren van netwerkfouten. Het geeft je geen toestemming, omzeilt geen rate limits en garandeert geen toegang. Of een crawl überhaupt een proxy nodig heeft, hangt af van het doel, de voorwaarden, de requestfrequentie en de betrouwbaarheidseisen van de klus.
Niet elke proxy is gelijk, en het verkeerde type kiezen kan op zichzelf al een productie-incident veroorzaken:
| Proxytype | Betrouwbaarheid | Snelheid | Detectierisico | Typische kosten |
|---|---|---|---|---|
| Gratis publieke proxies | Zeer wisselend | Wisselend | Vaak hoog | Geen fee, maar grote beveiligings-/operationele risico’s |
| Datacenter proxies | Afhankelijk van provider en target | Vaak snel | Afhankelijk van target | Vaak geprijsd per GB of IP |
| Residential proxies | Afhankelijk van provider en target | Wisselend | Afhankelijk van target | Vaak geprijsd per GB |
| ISP proxies | Afhankelijk van provider en target | Wisselend | Afhankelijk van target | Provider-specifiek |
Gratis proxies verdienen een aparte waarschuwing, omdat de gemeten risico’s aanzienlijk zijn. De 30 maanden durende Free Proxies Unmasked-studie volgde meer dan 640.000 adressen van 11 aanbieders: 34,5% was minstens één keer actief en 16.923 manipuleerden content. Die populatie onderstreept een stevige beveiligingswaarschuwing voor publieke lijsten; het is geen overdraagbaar faalpercentage voor elke actuele lijst, betaalde pool, target of workload.
Proxies verslaan moderne botdetectie ook niet automatisch. Diensten zoals Cloudflare scoren requests op basis van tientallen signalen — TLS-fingerprints, headerconsistentie, JavaScript-uitvoering, gedragspatronen — waarbij je IP-adres maar één factor is. Een schone residential proxy met inconsistente headers en zonder cookie jar wordt nog steeds gemarkeerd. Houd die verwachting dus realistisch voordat je een hele architectuur bouwt rond “gewoon de IP’s roteren”.
Voor je begint
- Moeilijkheid: Gemiddeld
- Benodigde tijd: ongeveer 30–45 minuten voor de volledige productieopzet, ongeveer 5 minuten voor de snelle test
- Wat je nodig hebt: Python 3.9+, Scrapy geïnstalleerd (deze gids is getest met Scrapy 2.17.0, uitgebracht in juli 2026), een werkende spider uit
scrapy startproject, en minstens één proxy-endpoint (een gratis trial van een datacenter-proxyprovider is prima voor tests)
Stap 1: Test een proxy met de request meta-parameter
De snelste manier om te checken of een proxy werkt, is even alle middleware-architectuur buitenspel zetten en het rechtstreeks proberen.
Scrapy’s ingebouwde HttpProxyMiddleware leest direct een proxy-key uit request.meta en routeert de request erdoorheen. Geen settings-aanpassingen, geen middleware-class — alleen één keyword argument.
import scrapy
class ProxyTestSpider(scrapy.Spider):
name = "proxy_test"
start_urls = ["https://httpbin.org/ip"]
def start_requests(self):
for url in self.start_urls:
yield scrapy.Request(
url,
meta={"proxy": "http://203.0.113.10:8080"},
callback=self.parse,
)
def parse(self, response):
self.logger.info(response.text)
Start het met scrapy runspider proxy_test.py. Als de proxy werkt, geeft httpbin.org/ip het IP-adres van de proxy terug in plaats van je eigen IP — dat is je bevestiging. Als de response blijft hangen en uiteindelijk een TCP connection timed out-fout geeft, is de proxy dood of onbereikbaar. En ja, dat gebeurt vaker dan proxy-aanbieders graag toegeven.
Deze methode is prima voor een losse spider of een snelle test. Maar zodra je meer dan één spider hebt, loopt het fout, omdat je dan dezelfde proxy-string in vijf verschillende bestanden hardcodeert.
Stap 2: Bouw een custom proxy middleware
Voor alles wat verder gaat dan één enkele spider wil je de proxylogica op één centrale plek hebben. Maak een ProxyMiddleware-class in middlewares.py:
from scrapy.exceptions import NotConfigured
class ProxyMiddleware:
def __init__(self, proxy_url):
self.proxy_url = proxy_url
@classmethod
def from_crawler(cls, crawler):
proxy_url = crawler.settings.get("PROXY_URL")
if not proxy_url:
raise NotConfigured("PROXY_URL is vereist; we vallen niet stilletjes terug op direct verkeer")
return cls(proxy_url=proxy_url)
def process_request(self, request, spider):
if "proxy" not in request.meta:
request.meta["proxy"] = self.proxy_url
En registreer die in settings.py:
import os
PROXY_URL = os.environ.get("PROXY_URL")
DOWNLOADER_MIDDLEWARES = {
"myproject.middlewares.ProxyMiddleware": 350,
}
Let op de from_crawler-classmethod in plaats van een gewone __init__. Dit is het patroon dat Scrapy zelf aanbeveelt voor het uitlezen van settings, en dezelfde hook gebruiken we in stap 4 opnieuw bij secrets. Het voordeel is simpel: verander één instelling, en elke spider in het project gebruikt meteen de nieuwe proxy. Niet meer vijf bestanden doorspitten om een dode IP te vervangen.
Stap 3: Begrijp de middleware-volgorde, zodat je proxy niet stilletjes niets doet
Dit is het deel dat bijna elke andere tutorial wegwuift met “zet de prioriteit gewoon op 350, vertrouw me maar”. Downloader middleware in Scrapy draait in een vaste, voorspelbare volgorde. Begrijp je die niet, dan krijg je bugs die totaal niets met proxies lijken te maken.
Request-hooks (process_request) lopen in oplopende prioriteit — laagste nummer eerst. Response-hooks (process_response, process_exception) lopen in aflopende prioriteit — hoogste nummer eerst, en werken terug door de keten.
Request flow (oplopend):
Spider → [100] RobotsTxt → [300] HttpAuth → [350] JOUW PROXY MIDDLEWARE
→ [500] UserAgent → [550] Retry → [700] Cookies → [750] HttpProxy
→ Downloader
Response flow (aflopend):
Downloader → [750] HttpProxy → [700] Cookies → [550] Retry
→ [500] UserAgent → [350] JOUW PROXY MIDDLEWARE → [300] HttpAuth
→ [100] RobotsTxt → Spider
Hier is de actuele standaard-prioriteitentabel voor Scrapy’s ingebouwde middleware (geverifieerd tegen 2.17.0):
| Middleware | Standaardprioriteit |
|---|---|
| RobotsTxtMiddleware | 100 |
| HttpAuthMiddleware | 300 |
| DownloadTimeoutMiddleware | 350 |
| DefaultHeadersMiddleware | 400 |
| UserAgentMiddleware | 500 |
| RetryMiddleware | 550 |
| RedirectMiddleware | 600 |
| CookiesMiddleware | 700 |
| HttpProxyMiddleware | 750 |
| DownloaderStats | 850 |
| HttpCacheMiddleware | 900 |
Wanneer RetryMiddleware een retry plant, kopieert het de mislukte request — inclusief metadata — en die nieuwe request komt opnieuw de downloader middleware-keten binnen. De numerieke relatie van je selector tot prioriteit 550 garandeert geen rotatie. Rotatie gebeurt alleen wanneer de selector-code de retry herkent en bewust de gekopieerde meta["proxy"] overschrijft. Prioriteit 350 is een handige plek voor een selector omdat die vóór de ingebouwde transportstap op 750 draait, maar het is op zichzelf geen rotatiemechanisme.

Veelvoorkomende fouten bij middleware-volgorde
- Je middleware op dezelfde prioriteit zetten als
HttpProxyMiddleware(750): dit creëert een race condition waarbij Scrapy’s dict-volgorde (niet jouw logica) bepaalt welke middleware de request eerst verwerkt. Symptom: af en toe, onverklaarbaar proxygedrag. setdefault()ofif "proxy" not in request.metagebruiken in een roterende selector: de gekopieerde retry behoudt de oude proxy. Symptom: elke retry gebruikt opnieuw dezelfde mislukte route. Oplossing: detecteer een retry (bijvoorbeeldretry_times > 0) en vervang expliciet de proxywaarde waar jouw selector eigenaar van is.HttpProxyMiddlewarevolledig uitschakelen: sommige tutorials zeggen dat je"scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware": Nonemoet zetten omdat “de custom middleware het afhandelt.” Dat klopt niet — je custom middleware is een selector, geen transportlaag. Schakel je de ingebouwde middleware uit, dan worden proxy-authenticatieheaders nooit toegevoegd en gaan je requests stilletjes ongeauthenticeerd weg (of helemaal niet).
Stap 4: Stop met proxy-inloggegevens hardcoden
Bij vrijwel elke top-ranking Scrapy-proxy tutorial die ik vond, staat http://username:password@proxy.example.com:8080 rechtstreeks in een Python-bestand. Dat is een credential die voor altijd in je Git-geschiedenis blijft staan, en die overal opduikt: in clones, forks en logdumpjes als iemand nonchalant met print() werkt.
Er zijn grofweg drie manieren om dit aan te pakken:
| Methode | Beveiliging | Flexibiliteit | Het best voor |
|---|---|---|---|
| Hardcoded in spider/settings.py | Slecht — secrets staan in de repo | Laag | Alleen snelle lokale tests |
Omgevingsvariabele http_proxy (Scrapy-native) | Beter — buiten de code | Laag (één proxy) | CI/CD-pipelines, Docker |
.env-bestand + python-dotenv + from_crawler | Beste — buiten de code, per omgeving | Hoog (meerdere proxies, rotatie) | Productiescrapers |
De derde optie is de moeite waard om goed op te zetten. Installeer python-dotenv, maak een .env-bestand aan en voeg het meteen toe aan .gitignore — serieus, doe dit nu:
PROXY_USER=myuser
PROXY_PASSWORD=my$ecret!Pass
PROXY_HOST=proxy.example.com
PROXY_PORT=8080
Laad het bovenaan in settings.py:
from dotenv import load_dotenv
import os
load_dotenv()
PROXY_USER = os.getenv("PROXY_USER")
PROXY_PASSWORD = os.getenv("PROXY_PASSWORD")
PROXY_HOST = os.getenv("PROXY_HOST")
PROXY_PORT = os.getenv("PROXY_PORT")
Lees het daarna veilig in je middleware via from_crawler — precies het patroon dat de verwarring oplost die ik op fora vaak zie, waar mensen vragen: “hoe zet ik dit vóór scrapy crawl als de credentials per run kunnen veranderen?”
import os
from urllib.parse import quote
class SecureProxyMiddleware:
def __init__(self, user, password, host, port):
self.user = quote(user, safe="")
self.password = quote(password, safe="")
self.host = host
self.port = port
@classmethod
def from_crawler(cls, crawler):
settings = crawler.settings
return cls(
user=settings.get("PROXY_USER"),
password=settings.get("PROXY_PASSWORD"),
host=settings.get("PROXY_HOST"),
port=settings.get("PROXY_PORT"),
)
def process_request(self, request, spider):
proxy_url = f"http://{self.user}:{self.password}@{self.host}:{self.port}"
request.meta["proxy"] = proxy_url
Let op de urllib.parse.quote()-aanroep rond de credentials. Als je wachtwoord een @, : of / bevat — en wachtwoordgeneratoren gooien die tekens er graag in — dan breekt de URL-parsing tenzij het eerst percent-encoded wordt. Dit is zo’n één-regel-fix die je een gênant uur debuggen bespaart van “invalid proxy URL”-fouten die niets met je proxy zelf te maken hebben.
Houd credentials uit logs en test percent-encoding met representatieve, maar neppe waarden. HTTPS-tunneling, SOCKS5 en niet-Latijnse credentials hebben handler-specifieke grenzen; ga er niet van uit dat een authenticatiepatroon overal werkt zonder een vastgepinde integratietest.

Stap 5: Voeg proxyrotatie toe
Zelfs een goede proxy die 5.000 requests naar dezelfde site stuurt, wordt uiteindelijk gemarkeerd. Je hebt een pool nodig.
Optie A — bouw het zelf. Dit is echt heel eenvoudig:
import random
class RotatingProxyMiddleware:
def __init__(self, proxy_pool):
self.proxy_pool = proxy_pool
@classmethod
def from_crawler(cls, crawler):
return cls(proxy_pool=crawler.settings.getlist("PROXY_POOL"))
def process_request(self, request, spider):
request.meta["proxy"] = random.choice(self.proxy_pool)
Dit werkt voor basaal gebruik, maar heeft geen enkel inzicht in welke proxies nog leven. Je gooit eigenlijk voor elke request de dobbelstenen.
Optie B — gebruik scrapy-rotating-proxies. Deze third-party package voegt standaard ban-detectie en automatische backoff toe:
pip install scrapy-rotating-proxies
Ik wil hier wel eerlijk over zijn: de laatste release op PyPI is versie 0.6.2 uit 2019, en het project is als Alpha getagd. Het is niet per se kapot op moderne Scrapy-versies, maar “niet actief onderhouden sinds 2019” is niet hetzelfde als “beproefd voor productieverkeer in 2026”. Pin de versie, test tegen je echte target-sites en ga er niet van uit dat het geauthenticeerde proxy-endpoints goed afhandelt — dat doet het grotendeels niet.
Stap 6: Bouw een fault-tolerant proxy middleware (detectie van dode proxies)
Dit is het onderdeel dat concurrenten meestal volledig overslaan, en het is precies het verschil tussen een demo en iets dat een crawl van 6 uur zonder toezicht overleeft.
| Scenario | Wat de meeste tutorials laten zien | Wat deze middleware toevoegt |
|---|---|---|
| Proxy geeft 407 terug | Niet behandeld | Behandelt dit als proxy-authenticatiefout |
| Target geeft 403/429 terug | Vaak op één hoop gegooid | Houdt beleids-/ratefeedback gescheiden van proxygezondheid |
| Proxy time-out | Niet behandeld | Instelbare time-outdrempel, afbouw van health score |
| Alle proxies dood | Niet behandeld | Graceful fallback of crawl-pauze met gelogde waarschuwing |
| Proxy flapt (intermitterend) | Niet behandeld | Afkoelperiode vóór opnieuw toevoegen aan de pool |
import time
import random
from scrapy.exceptions import IgnoreRequest
class FaultTolerantProxyMiddleware:
MAX_FAILURES = 3
COOLDOWN_SECONDS = 300
def __init__(self, proxy_pool):
self.pool = {p: {"failures": 0, "banned_until": 0} for p in proxy_pool}
@classmethod
def from_crawler(cls, crawler):
return cls(proxy_pool=crawler.settings.getlist("PROXY_POOL"))
def _healthy_proxies(self):
now = time.time()
return [p for p, s in self.pool.items() if s["banned_until"] < now]
def process_request(self, request, spider):
healthy = self._healthy_proxies()
if not healthy:
spider.logger.warning("Alle proxies zijn ongezond — crawl wordt gepauzeerd")
raise IgnoreRequest("Geen gezonde proxies beschikbaar")
request.meta["proxy"] = random.choice(healthy)
def process_response(self, request, response, spider):
proxy = request.meta.get("proxy")
if proxy and response.status == 407:
self._mark_failure(proxy)
return response
def process_exception(self, request, exception, spider):
proxy = request.meta.get("proxy")
if proxy:
self._mark_failure(proxy)
def _mark_failure(self, proxy):
state = self.pool[proxy]
state["failures"] += 1
if state["failures"] >= self.MAX_FAILURES:
state["banned_until"] = time.time() + self.COOLDOWN_SECONDS
state["failures"] = 0
Een paar opmerkingen uit de praktijk: behandel niet elke 403 als bewijs dat de proxy zelf dood is — RFC 9110 definieert 403 als “de server begreep het verzoek maar weigert het”, wat net zo goed kan betekenen dat je headers of sessie verdacht ogen, los van de proxy. Een 407 betekent daarentegen dat de proxy zelf je authenticatie afwijst — een sterker en specifieker signaal. Als je die signalen op één hoop gooit, verbrand je gezonde proxies zonder reden.
Maak Scrapy’s tijdelijke retry-defaults expliciet in productie, zodat reviewers het beleid kunnen zien:
RETRY_HTTP_CODES = [500, 502, 503, 504, 522, 524, 408, 429]
RETRY_TIMES = 2
Dit zijn de defaults van Scrapy 2.17. Voeg 403 of 407 niet zomaar toe: een 403 is een weigering door de target met meerdere mogelijke oorzaken, terwijl 407 een proxy-authenticatieprobleem is dat met generieke retries niet wordt opgelost. Als een specifiek targetcontract een andere status rechtvaardigt, documenteer die reden en test het apart.

Stap 7: Een meetbaar proxy-bij-retry-patroon
Sommige geautoriseerde targets leveren direct geldige content en hebben alleen een proxy nodig na een gedocumenteerde tijdelijke fout. Dat kan het aantal geproxiede bytes verlagen, maar er bestaat geen verdedigbaar universeel besparingspercentage of overdraagbaar direct-succespercentage. Meet je eigen workload voordat je dit patroon gebruikt.
Gebruik Scrapy’s publieke get_retry_request()-helper en beperk escalatie tot targetspecifieke statussen die je expliciet hebt geclassificeerd. Dit voorbeeld behandelt 429 en 503 als herprobeerbare druksignalen; 403 en 407 worden bewust uitgesloten.
from scrapy.downloadermiddlewares.retry import get_retry_request
class CostAwareEscalationMiddleware:
def process_response(self, request, response, spider):
if response.status not in {429, 503}:
return response
retry = get_retry_request(
request,
spider=spider,
reason=f"proxy_escalation_{response.status}",
max_retry_times=2,
)
if retry is None:
return response
current_tier = request.meta.get("proxy_tier", "direct")
if current_tier == "direct":
retry.meta["proxy"] = spider.settings["DATACENTER_PROXY"]
retry.meta["proxy_tier"] = "datacenter"
elif current_tier == "datacenter":
retry.meta["proxy"] = spider.settings["RESIDENTIAL_PROXY"]
retry.meta["proxy_tier"] = "residential"
else:
return response
return retry
Log het direct geldige-contentpercentage, het geproxiede geldige-contentpercentage, bytes per succesvol record, retries per succes en extra latency. Een direct-first ontwerp is alleen acceptabel wanneer directe toegang geautoriseerd is en het systeem fail-closed werkt zodra een proxy nodig is. De besparing is de gemeten daling in geproxied verkeer — niet een aangenomen percentage.
Wanneer zelf proxybeheer niet de moeite waard is
Ik wil hier eerlijk over zijn in plaats van te doen alsof de rest van dit artikel zinloos was: alles hierboven is echte, nuttige engineering, en voor veel projecten — crawls met hoge volumes, custom pipelines, alles waarbij je volledige controle over request scheduling nodig hebt — is dit gewoon de juiste keuze.
Maar als je echte doel is “gestructureerde data van deze pagina halen” in plaats van “proxy-infrastructuur beheren”, dan kan een extraction API een betere grens zijn. Thunderbit’s huidige POST /extract documentatie accepteert een pagina-URL en optioneel een JSON Schema; als je het schema weglaat, kan de service er zelf één genereren op basis van de pagina-inhoud. De endpoint biedt ook none, basic en full render-modi, plus instellingen voor time-out en wachten na laden. Prompt-only extractie maakt geen deel uit van de huidige ondersteunde request-surface, dus bouw productie-integraties rond het gedocumenteerde schema-contract. Dit verplaatst de extractie-interface achter één request; het is geen universele belofte voor elk anti-bot- of CAPTCHA-target.
| Factor | DIY Scrapy + proxies | API-gebaseerde extractie (bijv. Thunderbit) |
|---|---|---|
| Opzetinspanning | Hoog — middleware, rotatie, retry-logica | Laag — één API-call met een schema |
| Netwerk-/rendergedrag | Jij configureert handlers, proxies, headers en delays | Gereguleerd via gedocumenteerde API-opties |
| Onderhoud | Jij beheert selectors, poolgezondheid en targetwijzigingen | Jij beheert schema-kwaliteit, validatie en integratiegedrag |
| Kostenmodel | Proxykosten + compute + engineeringtijd | Huidige docs vermelden 20 units per pagina (gecontroleerd 2026-08-10) |
| Controle | Volledig — custom pipelines, middleware-keten | Beperkt tot API-mogelijkheden |
| Het best voor | Complexe crawls, hoge volumes, custom logica | Gerichte extractie, prototyping, verrijking |
Als je vooral gestructureerde pagina’s extraheert voor leadlijsten, productdata of onderzoek, doe dan een representatieve pilot met de Thunderbit Chrome Extension of de API en vergelijk valide records, latency, units en onderhoudstijd. Heeft je project custom crawl-graphs en pipelinecontrole nodig, dan blijft Scrapy de sterkere keuze.
Meer lezen
Tips en veelvoorkomende valkuilen
- Tip: Test proxies eerst op
httpbin.org/ipvoordat je ze op een echte target loslaat. Dat is de snelste manier om te checken of routing werkt voordat je extra complexiteit toevoegt. - Valkuil: Een proxy instellen in
request.headersin plaats vanrequest.meta. Dit is een verrassend vaak voorkomende typfoutachtige bug —HttpProxyMiddlewareleest alleenmeta["proxy"], en een header-gebaseerde poging mislukt stilletjes zonder duidelijke fout. - Valkuil: Aannemen dat HTTP- en HTTPS-proxies identiek geconfigureerd worden. Een HTTP-proxy-URL die naar een HTTPS-doel routeert, werkt doorgaans via CONNECT-tunneling onder een compatibele handler, maar een
https://-schema voor het proxy-endpoint zelf is een andere, minder goed ondersteunde configuratie — haal die twee niet door elkaar. - Tip: Als je SOCKS5-ondersteuning nodig hebt, check dan eerst de download-handler-mogelijkheden van je Scrapy-versie. Scrapy 2.17’s experimentele Httpx handler voegde SOCKS5-ondersteuning toe via
httpx[socks], maar dit blijft experimenteel — bouw hier geen productieafhankelijkheid op zonder eigen tests.
Alternatieve methoden
Naast scrapy-rotating-proxies sturen sommige teams alle proxylogica via een provider-gateway: één proxy-URL waarbij de aanbieder rotatie, sessiestickiness en geo-targeting achter de schermen regelt. Dat geeft wat minder controle op, maar aanzienlijk minder middleware-code, en het is de moeite waard om de kosten te vergelijken met een zelf beheerde pool voordat je alles vanaf nul bouwt.
Conclusie
Een proxy instellen in Scrapy kost één regel. Maar die setup echt overeind houden tijdens een productie-crawl vraagt om expliciet foutbeleid, afgeschermde credentials, geteste handler-grenzen en selector-code die gekopieerde proxy-metadata bij een retry bewust vervangt. Neem twee gewoontes mee: fail closed wanneer een proxy vereist is, en commit nooit een proxywachtwoord in een Python-bestand.
FAQ’s
Hoe stel ik een custom proxy met authenticatie in Scrapy in?
Gebruik de URL-notatie protocol://username:password@host:port, maar percent-encode de gebruikersnaam en het wachtwoord eerst met urllib.parse.quote() als er speciale tekens in zitten. Lees die credentials in productie via een from_crawler-classmethod uit omgevingsvariabelen in plaats van ze hard te coderen.
Welke prioriteitswaarde moet ik gebruiken voor mijn custom proxy middleware in Scrapy?
350 is een veelgebruikte selectorprioriteit omdat die vóór HttpProxyMiddleware op 750 draait. Dat garandeert geen rotatie. Een retry krijgt pas een nieuwe proxy als de selector de gekopieerde retry-request herkent en de eerdere meta["proxy"]-waarde overschrijft.
Hoe handel ik dode proxies automatisch af in Scrapy?
Bouw een middleware die per proxy failure-counts bijhoudt in process_response en process_exception, proxies na een drempel uit de actieve pool haalt en ze na een afkoelperiode weer terugzet in plaats van ze permanent te blokkeren.
Kan ik Scrapy gebruiken met SOCKS5-proxies?
Scrapy 2.17’s experimentele HttpxDownloadHandler documenteert SOCKS5-ondersteuning wanneer httpx[socks] is geïnstalleerd. De standaard HTTP/1.1-handler ondersteunt geen SOCKS-proxies. Pin de handler en versie vast en voer een integratietest uit voordat je dit pad productiegeschikt noemt.
Hoeveel kan het proxy-bij-retry-patroon echt besparen op proxykosten?
Er is geen overdraagbaar percentage. Meet welk deel van de geautoriseerde requests direct geldige content oplevert, hoeveel bytes via elke proxylaag lopen, hoeveel retries er per succesvol record nodig zijn en hoeveel latency erbij komt. De geobserveerde daling in geproxied verkeer is je besparing; als direct-first toegang niet geautoriseerd of niet geldig is, gebruik dit patroon dan niet.


