Så ställer du in en anpassad proxy i Scrapy (produktionsklar)

Senast uppdaterad August 11, 2026
Hand-drawn Scrapy crawler routing through a proxy pool, retrying a 503 route and completing through a 200 route
AI-sammanfattning
  • Bygg en egen Scrapy proxy-middleware som tilldelar godkända rutter, lägger till autentisering på ett säkert sätt, loggar felorsaker och bevarar request-metadata mellan retries.
  • Förstå ordningen i downloader middleware, särskilt hur egen proxylogik samspelar med HttpProxyMiddleware, RetryMiddleware, redirects och exception-hantering.
  • Lägg till rotation med begränsade försök, nedkylningsperioder, proxyhälsostatus och målinriktade regler i stället för att välja en slumpmässig proxy för varje request.
  • Skilj mellan proxyautentiseringsfel, anslutningsfel, DNS-problem, 403-svar från målet och rate limits så att varje tillstånd får rätt åtgärd.
  • Använd produktionsskydd för lagring av hemligheter, concurrency, observability, sessionskonsistens och fail-closed-beteende när inga godkända proxies finns kvar.

Din Scrapy-spider glänser på 100 testsidor och rasar sedan ihop vid 10 000. Det där är egentligen inte ett scrapesfel — det är ett nätverksproblem som bara råkar se ut som ett scrapesfel. Lösningen många väljer är en proxy, och att stoppa in den i request.meta tar ungefär trettio sekunder.

Problemet är att den där trettiosekunderslösningen ofta är där de flesta grundläggande guider slutar. De visar meta={"proxy": "http://IP:PORT"}, kanske en middleware-klass, och nöjer sig där. Ofta hoppar de över vad som händer när proxyn dör mitt i en crawl, hur inloggningsuppgifter läcker in i Git-historiken, eller varför ett nytt försök kan återanvända samma misslyckade proxy. Det är just de produktionsfrågor den här guiden tar upp: fail-closed-konfiguration, hantering av hemligheter, medvetet proxyval vid retries, protokollbegränsningar och mätbara kostnadsavvägningar.

Vad är en proxy-middleware i Scrapy?

En proxy-middleware är kod som ligger i Scrapys downloader-pipeline och bestämmer vilken IP-adress en request ska se ut att komma från innan den skickas ut på nätet. Scrapy levererar en inbyggd sådan, HttpProxyMiddleware, som läser nyckeln proxy från request.meta, lägger till proxy-autentisering om det behövs och skickar sedan vidare requesten till download-handlern som faktiskt öppnar anslutningen. En egen proxy-middleware ersätter inte det steget — den fungerar som en väljare som avgör vilken proxy som ska användas innan den inbyggda mekaniken tar över. Den skillnaden spelar större roll än man först tror, och den ligger bakom många felrapporter i stil med “min custom middleware fungerar inte”.

Varför proxies spelar roll i Scrapy-projekt för produktion

En proxy ändrar nätverksvägen och den IP-adress som verkar vara källan. Det kan hjälpa vid legitim testning för olika geografiska marknader, fördela godkänd requesttrafik och isolera nätverksfel. Den ger inte tillstånd, kringgår inte rate limits och garanterar inte åtkomst. Om en crawl alls behöver proxy beror på målet, villkoren, requesttakten och hur tillförlitlig körningen måste vara.

Alla proxies är inte likadana, och att välja fel nivå är i sig ett produktionsproblem:

ProxytypTillförlitlighetHastighetRisk att upptäckasTypisk kostnad
Gratis publika proxiesMycket varierandeVarierandeOfta högIngen avgift, men betydande säkerhets- och driftsrisk
Datacenter-proxiesBeror på leverantör och målOfta snabbBeror på måletOfta prissatt per GB eller per IP
Residential-proxiesBeror på leverantör och målVarierandeBeror på måletOfta prissatt per GB
ISP-proxiesBeror på leverantör och målVarierandeBeror på måletLeverantörsspecifikt

Gratis proxies förtjänar ett särskilt tillägg eftersom de uppmätta riskerna är stora. Den 30 månader långa studien Free Proxies Unmasked följde mer än 640 000 adresser från 11 leverantörer: 34,5 % var aktiva minst en gång och 16 923 manipulerade innehåll. Det underlaget räcker för en tydlig säkerhetsvarning kring publika listor; det är inte en överförbar felfrekvens för varje aktuell lista, betald pool, målsite eller arbetslast.

Proxies trollar inte heller bort modern botdetektering. Tjänster som Cloudflare poängsätter requests med hjälp av dussintals signaler — TLS-fingeravtryck, header-konsistens, JavaScript-exekvering, beteendemönster — där din IP-adress bara är en av flera ingångar. En ren residential proxy med inkonsekventa headers och ingen cookie jar kommer fortfarande att flaggas. Håll förväntningarna realistiska innan du bygger hela arkitekturen kring “byt bara IP”.

Innan du börjar

  • Svårighetsgrad: Medel
  • Tidsåtgång: Cirka 30–45 minuter för en komplett produktionslösning, cirka 5 minuter för snabbtestet
  • Det du behöver: Python 3.9+, Scrapy installerat (guiden är testad mot Scrapy 2.17.0, släppt i juli 2026), en fungerande spider från scrapy startproject och minst en proxy-endpoint (en gratis testperiod från valfri datacenter-proxy-leverantör fungerar bra för test)

Steg 1: Testa en proxy med request-meta-parametern

Det snabbaste sättet att kontrollera att en proxy fungerar är att helt hoppa över middleware-arkitekturen och bara prova den direkt.

Scrapys inbyggda HttpProxyMiddleware läser nyckeln proxy direkt ur request.meta och skickar requesten genom den. Inga ändringar i settings, ingen middleware-klass — bara ett nyckelvärde.

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)

Kör den med scrapy runspider proxy_test.py. Om proxyn fungerar kommer httpbin.org/ip att visa proxy-IP:n i stället för din egen — det bekräftar att allt är rätt kopplat. Om svaret hänger och till slut ger felet TCP connection timed out är proxyn död eller otillgänglig, vilket, som en spoiler, händer oftare än proxy-leverantörer gärna medger.

Den här metoden är okej för enstaka spiders eller snabba tester. Den faller isär så fort du har fler än en spider, eftersom du då hårdkodar samma proxysträng i fem olika filer.

Steg 2: Bygg en egen proxy-middleware

För allt som är mer än en enda spider vill du centralisera proxylogiken på ett ställe. Skapa en ProxyMiddleware-klass i projektets 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 required; refusing silent direct fallback")
        return cls(proxy_url=proxy_url)

    def process_request(self, request, spider):
        if "proxy" not in request.meta:
            request.meta["proxy"] = self.proxy_url

Och registrera den i settings.py:

import os

PROXY_URL = os.environ.get("PROXY_URL")

DOWNLOADER_MIDDLEWARES = {
    "myproject.middlewares.ProxyMiddleware": 350,
}

Lägg märke till from_crawler-klassmetoden i stället för en vanlig __init__. Det här är det mönster Scrapy faktiskt rekommenderar för att läsa settings, och det är samma hook vi kommer att använda igen i steg 4 när vi pratar om hemligheter. Fördelen är enkel: ändra en inställning, så plockar alla spiders i projektet upp den nya proxyn. Inget mer letande i fem filer för att byta en död IP.

Steg 3: Förstå middleware-ordningen så att din proxy inte tyst slutar fungera

Här är delen som nästan alla andra guider sveper förbi med “sätt bara prioriteten till 350, lita på mig”. Downloader middleware i Scrapy körs i en specifik och förutsägbar ordning, och om du inte förstår den kommer din proxykonfiguration att ge buggar som ser helt orelaterade ut.

Request-hakar (process_request) körs i stigande prioritetsordning — lägsta tal först. Response-hakar (process_response, process_exception) körs i fallande ordning — högsta tal först, på väg tillbaka nedför kedjan.

Requestflöde (stigande):
  Spider → [100] RobotsTxt → [300] HttpAuth → [350] DIN PROXY-MIDDLEWARE
         → [500] UserAgent → [550] Retry → [700] Cookies → [750] HttpProxy
         → Downloader

Responseflöde (fallande):
  Downloader → [750] HttpProxy → [700] Cookies → [550] Retry
             → [500] UserAgent → [350] DIN PROXY-MIDDLEWARE → [300] HttpAuth
             → [100] RobotsTxt → Spider

Här är den faktiska, aktuella standardtabellen för Scrapys inbyggda middlewares (verifierad mot 2.17.0):

MiddlewareStandardprioritet
RobotsTxtMiddleware100
HttpAuthMiddleware300
DownloadTimeoutMiddleware350
DefaultHeadersMiddleware400
UserAgentMiddleware500
RetryMiddleware550
RedirectMiddleware600
CookiesMiddleware700
HttpProxyMiddleware750
DownloaderStats850
HttpCacheMiddleware900

När RetryMiddleware schemalägger ett nytt försök kopierar den den misslyckade requesten — inklusive metadata — och den nya requesten går in i downloader middleware-kedjan igen. Väljarens numeriska relation till prioritet 550 garanterar inte rotation. Rotation sker bara när väljarkoden känner igen retry-försöket och medvetet skriver över den kopierade meta["proxy"]. Prioritet 350 är ett praktiskt ställe för en selector eftersom den körs före det inbyggda transportsteget vid 750, men den är inte en rotationsmekanism i sig.

Scrapys request- och responsevägar genom prioritet 350, 550 och 750, med en 503-retry som går in i middleware-kedjan igen

Vanliga misstag med middleware-ordning

  • Att sätta din middleware på samma prioritet som HttpProxyMiddleware (750): Det skapar en race condition där Scrapys ordboksordning (inte din logik) avgör vilken middleware som hanterar requesten först. Symtom: ojämnt och oförklarligt proxybeteende.
  • Att använda setdefault() eller if "proxy" not in request.meta i en roterande selector: den kopierade retry-requesten behåller den gamla proxyn. Symtom: varje retry upprepar samma misslyckade väg. Lösning: identifiera en retry (till exempel retry_times > 0) och ersätt uttryckligen det proxyvärde som selectionen äger.
  • Att stänga av HttpProxyMiddleware helt: Vissa guider säger att du ska sätta "scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware": None eftersom “den egna middlewaren hanterar det”. Det gör den inte — din egen middleware är en selector, inte transportlagret. Om den inbyggda stängs av attachas aldrig proxy-autentiseringshuvuden, och dina requests går tyst ut utan autentisering (eller inte alls).

Steg 4: Sluta hårdkoda proxyuppgifter

Varenda Scrapy-guide om proxies som ligger högt i sökresultaten skriver http://username:password@proxy.example.com:8080 direkt i en Python-fil. Det är en hemlighet som sedan lever kvar i Git-historiken för alltid och dyker upp i varje clone, varje fork och varje loggdump om någon är slarvig med print().

Det finns i praktiken tre nivåer av att göra detta:

MetodSäkerhetFlexibilitetBäst för
Hårdkodat i spider/settings.pyDålig — hemligheter lever i repotLågEndast snabb lokal testning
Miljövariabeln http_proxy (Scrapy-native)Bättre — utanför kodenLåg (en proxy)CI/CD-pipelines, Docker
.env-fil + python-dotenv + from_crawlerBäst — utanför koden, per miljöHög (flera proxies, rotation)Produktionsscrapers

Det tredje alternativet är värt att bygga ordentligt. Installera python-dotenv, skapa en .env-fil (och lägg direkt till den i .gitignore — jag menar det, gör det nu):

PROXY_USER=myuser
PROXY_PASSWORD=my$ecret!Pass
PROXY_HOST=proxy.example.com
PROXY_PORT=8080

Ladda den högst upp i 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")

Läs sedan in värdena säkert i din middleware med from_crawler — det här är mönstret som löser precis den förvirring jag sett på forum där folk frågar “hur sätter jag detta innan jag kör scrapy crawl om uppgifterna måste ändras per körning?”:

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

Lägg märke till urllib.parse.quote() kring inloggningsuppgifterna. Om ditt lösenord innehåller @, : eller / — och lösenordsgeneratorer älskar att slänga in sådana tecken — så går URL-parsningen sönder om det inte percent-enkodas först. Det är en liten fix som kan spara en pinsam timme av felsökning av “invalid proxy URL” trots att själva proxyn är helt okej.

Håll credentials borta från loggar och testa percent-encoding med representativa — men fejkade — värden. HTTPS-tunnling, SOCKS5 och icke-latinska tecken har gränser som beror på handlern; anta inte att ett autentiseringsmönster fungerar överallt utan ett låst integrationstest.

Säker flödesbild från en låst miljöfil via percent-enkodade proxyinställningar in i Scrapys request-metadata

Steg 5: Lägg till proxyrotation

En enda proxy — även en bra sådan — som gör 5 000 requests mot samma sajt kommer till slut att flaggas. Du behöver en pool.

Alternativ A — bygg det själv. Det här är verkligen enkelt:

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)

Det här fungerar för enklare bruk, men har noll koll på vilka proxies som faktiskt lever. Du kastar tärning vid varje request.

Alternativ B — använd scrapy-rotating-proxies. Det här tredjepartspaketet lägger till ban-detektering och automatisk backoff direkt:

pip install scrapy-rotating-proxies

Jag vill vara helt ärlig här: den senaste versionen på PyPI är 0.6.2, daterad 2019, och projektet är märkt Alpha. Det betyder inte nödvändigtvis att det är trasigt i modern Scrapy, men “inte aktivt underhållet sedan 2019” är inte samma sak som “bevisat för produktionsflöden 2026.” Lås versionen, testa den mot dina faktiska mål och anta inte att den hanterar autentiserade proxy-endpoints — det gör den i stort sett inte.

Steg 6: Bygg en feltålig proxy-middleware (detektering av döda proxies)

Det här är avsnittet som varje konkurrentguide hoppar över helt, och det är skillnaden mellan en demo och något som överlever en sex timmar lång crawl utan tillsyn.

ScenarioVad de flesta guider visarVad denna middleware lägger till
Proxy returnerar 407Inte adresseratBehandlar det som ett proxy-autentiseringsfel
Målet returnerar 403/429Ofta ihopklumpatHåller policy-/rate-limitsignaler separata från proxyhälsa
Proxy time-out:arInte adresseratKonfigurerbar timeouttröskel, hälsopoäng som sjunker
Alla proxies är dödaInte adresseratGraciös fallback eller crawl-paus med varningslogg
Proxy flappar (intermittent)Inte adresseratNedkylningsperiod innan den läggs tillbaka i poolen
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("All proxies unhealthy — pausing crawl")
            raise IgnoreRequest("No healthy proxies available")
        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

Några praktiska saker från faktisk byggning av detta: behandla inte varje 403 som bevis för att proxyn är död — RFC 9110 definierar 403 som att servern förstår men vägrar, vilket lika gärna kan betyda att dina headers eller session ser misstänkta ut, oavsett proxy. En 407 däremot betyder att proxyn specifikt nekar din autentisering — det är en starkare och mer specifik signal. Att blanda ihop de signalerna i samma bucket är så man börjar bränna friska proxies i onödan.

Håll Scrapys tillfälliga retry-standarder explicita i produktion så att granskare kan se policyn:

RETRY_HTTP_CODES = [500, 502, 503, 504, 522, 524, 408, 429]
RETRY_TIMES = 2

Det är Scrapy 2.17:s standardvärden. Lägg inte slentrianmässigt till 403 eller 407: en 403 är ett avslag från målet med många möjliga orsaker, medan en 407 är ett proxy-autentiseringsproblem som generisk request-retry inte kommer att lösa. Om ett specifikt målkontrakt motiverar att du retry:ar en annan status, dokumentera orsaken och testa den separat.

Tydlig hantering av 407-autentiseringsfel, 429 rate limiting, 503 retry, 200 success och en stängd grind när proxies saknas

Steg 7: Ett mätbart mönster för proxy vid retry

Vissa godkända mål kan ge giltigt innehåll direkt och bara behöva proxy efter ett dokumenterat tillfälligt svar. Det kan minska mängden proxyt trafik, men det finns ingen försvarbar universell besparing i procent eller någon överförbar direkt-förfrågningsgrad. Mät din egen arbetslast innan du använder mönstret.

Använd Scrapys publika hjälpfunktion get_retry_request() och håll upptrappning begränsad till målspecifika statusar som du uttryckligen har klassificerat. Det här exemplet behandlar 429 och 503 som retrybara signaler om belastning; 403 och 407 är medvetet exkluderade.

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

Logga andelen direktanrop som ger giltigt innehåll, andelen proxade anrop som ger giltigt innehåll, bytes per lyckad post, antal retries per lyckat resultat och extra latens. En direct-first-design är bara acceptabel när direkt åtkomst är godkänd och systemet fail-closed när en proxy faktiskt krävs. Besparingen är den uppmätta minskningen i proxad trafik — inte en antagen procentsats.

När det inte är värt att bygga egen proxyhantering

Jag vill vara tydlig här i stället för att låtsas som om resten av artikeln var meningslös: allt ovan är riktig och användbar ingenjörskonst, och för många projekt — högvolymscrawls, egna pipelines, allt där du behöver full kontroll över request-schemaläggning — är det helt rätt väg.

Men om ditt faktiska mål är “få strukturerad data från den här sidan” snarare än “drifta proxyinfrastruktur”, kan ett extraktions-API vara en bättre gräns. Thunderbits nuvarande POST /extract-dokumentation accepterar en sid-URL och ett valfritt JSON Schema; när schema utelämnas kan tjänsten generera ett från sidans innehåll. Endpunkten erbjuder också renderlägena none, basic och full, tillsammans med timeout- och wait-kontroller efter laddning. Prompt-only-extraktion ingår inte i dagens stödda request-yta, så bygg produktionsintegrationer kring det dokumenterade schema-kontraktet. Detta flyttar extraktionsgränssnittet bakom en enda request; det är inte en generell garanti mot alla anti-bot- eller CAPTCHA-mål.

FaktorEgen Scrapy + proxiesAPI-baserad extraktion (t.ex. Thunderbit)
UppstartHög — middleware, rotation, retry-logikLåg — ett API-anrop med schema
Nätverks-/renderingsbeteendeDu konfigurerar handlers, proxies, headers och fördröjningarStyrs via dokumenterade API-alternativ
UnderhållDu äger selectors, poolhälsa och måländringarDu äger schemakvalitet, validering och integrationsbeteende
KostnadsmodellProxyavgifter + beräkning + ingenjörstidAktuell dokumentation anger 20 enheter per sida (kontrollerat 2026-08-10)
KontrollFull — egna pipelines, middleware-kedjaBegränsad till API:ets möjligheter
Bäst förKomplexa crawls, hög volym, egen logikRiktad extraktion, prototyper, enrichment

Om du mest extraherar strukturerade sidor för leadlistor, produktdata eller research, kör ett representativt pilotförsök med Thunderbit Chrome Extension eller API:t och jämför giltiga poster, latency, enheter och underhållstid. Om projektet behöver egna crawl-grafer och kontroll över pipelinen är Scrapy fortfarande det starkare valet.

Läs mer

Tips och vanliga fallgropar

  • Tips: Testa proxies mot httpbin.org/ip innan du pekar dem mot ett riktigt mål. Det är det snabbaste sättet att bekräfta att routingen fungerar innan du lägger till mer komplexitet.
  • Fallgrop: Att sätta en proxy i request.headers i stället för request.meta. Det här är ett väldigt vanligt gränsfall av typo-bugg — HttpProxyMiddleware läser bara meta["proxy"], och ett försök via header kommer att misslyckas tyst utan tydligt felmeddelande.
  • Fallgrop: Att anta att HTTP- och HTTPS-proxies konfigureras identiskt. En HTTP-proxy-URL som routar till en HTTPS-destination fungerar vanligtvis via CONNECT-tunnling med en kompatibel handler, men att använda schemat https:// för själva proxy-endpointen är en annan och mindre stödd konfiguration — blanda inte ihop de två.
  • Tips: Om du behöver SOCKS5-stöd, kontrollera först vilken support din Scrapy-version har i download-handlers. Scrapy 2.17:s experimentella Httpx-handler lade till SOCKS5-stöd via httpx[socks], men den är fortfarande märkt experimentell — bygg inte en produktionsberoende lösning på den utan egna tester.

Alternativa metoder

Utöver scrapy-rotating-proxies skickar vissa team all proxylogik genom en leverantörsgateway — en enda proxy-URL där leverantören sköter rotation, sessionsklibbighet och geotargeting bakom kulisserna. Det innebär lite mindre kontroll men också betydligt mindre middleware-kod, och det kan vara värt att prisjämföra mot en egen pool innan du bygger allt från grunden.

Slutsats

Att sätta en proxy i Scrapy tar en rad kod. Att få den lösningen att överleva en riktig produktionscrawl kräver en tydlig felpolicy, skyddade hemligheter, testade gränser för handlers och selector-kod som medvetet ersätter kopierad proxy-metadata vid retry. Om du bara tar med dig två vanor, låt dem vara dessa: fail closed när en proxy krävs, och checka aldrig in ett proxy-lösenord i en Python-fil.

Vanliga frågor

Hur ställer jag in en anpassad proxy i Scrapy med autentisering? Använd formatet protocol://username:password@host:port, men percent-enkoda först användarnamn och lösenord med urllib.parse.quote() om de innehåller specialtecken. I produktion bör du läsa in dessa uppgifter via en from_crawler-klassmetod som hämtar dem från miljövariabler i stället för att hårdkoda dem.

Vilket prioritetsnummer ska jag använda för min egna proxy-middleware i Scrapy? 350 är en vanlig selector-prioritet eftersom den körs före HttpProxyMiddleware vid 750. Det garanterar inte rotation. En retry får en ny proxy bara om selector-koden känner igen den kopierade retry-requesten och skriver över dess tidigare värde i meta["proxy"].

Hur hanterar jag döda proxies automatiskt i Scrapy? Bygg en middleware som spårar antal fel per proxy i process_response och process_exception, tar bort proxies från den aktiva poolen efter en feltröskel och lägger tillbaka dem efter en nedkylningsperiod i stället för att blockera dem permanent.

Kan jag använda Scrapy med SOCKS5-proxies? Scrapy 2.17:s experimentella HttpxDownloadHandler dokumenterar SOCKS5-stöd när httpx[socks] är installerat. Den vanliga HTTP/1.1-handlern stöder inte SOCKS-proxies. Lås handler/version och kör ett integrationstest innan du betraktar vägen som produktionsklar.

Hur mycket kan proxy-vid-retry-mönstret faktiskt spara i proxykostnad? Det finns ingen portabel procentsats. Mät andelen godkända requests som ger giltigt innehåll direkt, antal bytes som går genom varje proxy-nivå, retries per lyckad post och extra latens. Den observerade minskningen av proxad trafik är din besparing; om direct-first-åtkomst inte är godkänd eller inte fungerar, ska du inte använda det här mönstret.

Ke
Ke
CTO på Thunderbit | Senior data scientist & ML-expert Med nästan ett decenniums erfarenhet inom maskininlärning och datavetenskap är Ke Shen alumn från Columbia University och tidigare Senior Data Scientist på Walmart Labs. Med djup, av branschen erkänd expertis inom Python, R, Java och statistik delar han väl beprövade insikter om hur man förvandlar komplexa AI-algoritmer från teori till produktionsklar arkitektur.
Topics
Scrapy proxy middlewarePython-webbscrapingProxyrotation
Innehållsförteckning
Thunderbit · AI-agent för webdata

Extrahera data från vilken sida som helst på 1 klick

Används av över 250 000 användare
gratis plan finns
Från webbsida till kalkylark
Beskriv vad du behöver — Thunderbits AI-agent samlar in det och exporterar till Excel, Google Sheets, Airtable eller Notion. Gratis att börja med.
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week