Scrapy Proxy Middleware: Kumpletong Configuration Guide (2026)

Na-publish noong 4 Hunyo 2026 · ≈11 min na pagbasa

Ang Scrapy pa rin ang workhorse para sa mga production crawl sa 2026 — at ang framework pa rin kung saan pinakanalilito ang mga tao sa proxy setup, dahil may apat na magkakaibang lugar kung saan maipapasok ang proxy at tatlo sa mga ito ay mali para sa karamihan ng proyekto. Ibinibigay sa iyo ng gabay na ito ang tama: isang maliit na custom middleware na may per-request routing, sticky sessions, ban detection, at matinong retry behavior.

Kung nasa simpleng requests/httpx/aiohttp ka naman, tingnan ang How to Rotate Proxies in Python. Ang artikulong ito ay Scrapy-specific.

Ang 30-Second na Bersyon

Para sa rotating residential gateway, ang minimum viable setup ay isang linya kada request — walang middleware na kailangan:

def start_requests(self):
    for url in self.urls:
        yield scrapy.Request(
            url,
            meta={"proxy": "http://USERNAME:[email protected]:913"},
        )

Binabasa ng built-in na HttpProxyMiddleware ng Scrapy ang request.meta["proxy"] at hina-handle ang authentication mula sa URL. Iro-rotate ng gateway ang exit IP para sa iyo. Kung iyon lang ang kailangan mo, huminto rito. Ang natitira sa gabay na ito ay para kapag kailangan mo ng kontrol: sticky sessions, country routing, ban-aware rotation, at concurrency tuning.

Isang Production Proxy Middleware

Ilagay ito sa middlewares.py. Nag-aassign ito ng sticky sessions kada domain, nag-ro-rotate kapag may ban, at tina-tag ang bawat request para ma-debug mo kung aling session ang kumuha ng ano:

import random
import string

GATEWAY = "us.jibaoproxy.com:913"
USERNAME = "USERNAME"          # move to settings.py / env in real projects
PASSWORD = "PASSWORD"

def _new_session(n=8):
    return "".join(random.choices(string.ascii_lowercase + string.digits, k=n))

class JibaoProxyMiddleware:
    """Sticky session per domain; rotate session on ban."""

    def __init__(self):
        self.sessions = {}          # domain -> session id

    def _proxy_url(self, session_id):
        user = f"{USERNAME}-session-{session_id}"
        return f"http://{user}:{PASSWORD}@{GATEWAY}"

    def process_request(self, request, spider):
        domain = request.url.split("/")[2]
        session = self.sessions.setdefault(domain, _new_session())
        request.meta["proxy"] = self._proxy_url(session)
        request.meta["proxy_session"] = session

    def rotate(self, domain):
        """Call when a session is burned."""
        self.sessions[domain] = _new_session()

At isang kasamang downloader middleware na nakakatukoy ng mga ban at nag-re-retry sa sariwang session:

from scrapy.downloadermiddlewares.retry import RetryMiddleware
from scrapy.utils.response import response_status_message

BAN_CODES = {403, 429}
BAN_MARKERS = (b"captcha", b"access denied", b"unusual traffic")

class BanAwareRetryMiddleware(RetryMiddleware):

    def process_response(self, request, response, spider):
        banned = (
            response.status in BAN_CODES
            or any(m in response.body[:2048].lower() for m in BAN_MARKERS)
        )
        if banned:
            domain = request.url.split("/")[2]
            proxy_mw = spider.crawler.engine.downloader.middleware.middlewares
            for mw in proxy_mw:
                if hasattr(mw, "rotate"):
                    mw.rotate(domain)        # burn the session
            reason = response_status_message(response.status)
            return self._retry(request, reason, spider) or response
        return super().process_response(request, response, spider)

I-wire ang dalawa sa settings.py:

DOWNLOADER_MIDDLEWARES = {
    "myproject.middlewares.JibaoProxyMiddleware": 350,
    "scrapy.downloadermiddlewares.retry.RetryMiddleware": None,   # replace stock retry
    "myproject.middlewares.BanAwareRetryMiddleware": 550,
}
RETRY_TIMES = 2

Mahalaga ang priority: dapat tumakbo ang proxy middleware bago ang HttpProxyMiddleware (750) ng Scrapy, kaya gumagana ang anumang nasa ilalim ng 750; pinapanatili ng 350 itong maaga at predictable.

Sticky vs Rotating: Aling Mode para sa Aling Spider

Uri ng crawlModeImplementasyon
Stateless page harvestingRotatingTahasang username, nag-ro-rotate ang gateway kada request
Login + crawl sa likod ng authSticky kada account-session-{account_id}, huwag kailanman i-rotate sa kalagitnaan ng login
Pagination-heavy na listingsSticky kada domain, mag-rotate kapag may banAng middleware sa itaas
Geo-specific na pricingRotating + country pinUSERNAME-country-de style na mga parameter

Mas malalim na pagtalakay sa trade-off na ito: Sticky vs Rotating Proxy Sessions.

Mga Concurrency Setting na Hindi Ka Mapapa-ban

Ang mga default ng Scrapy ay nakatutok para sa magalang na single-IP crawling. Sa likod ng rotating pool maaari kang magtulak nang mas malakas — pero mahalaga pa rin ang per-domain limits dahil nakikita ng target ang aggregate behavior:

# settings.py - sane starting point behind a residential pool
CONCURRENT_REQUESTS = 64
CONCURRENT_REQUESTS_PER_DOMAIN = 8     # what the target experiences
DOWNLOAD_DELAY = 0.25                  # jitter applied per slot
RANDOMIZE_DOWNLOAD_DELAY = True        # 0.5x-1.5x the delay
AUTOTHROTTLE_ENABLED = True
AUTOTHROTTLE_TARGET_CONCURRENCY = 6.0
DOWNLOAD_TIMEOUT = 30
ROBOTSTXT_OBEY = True

Itaas ang CONCURRENT_REQUESTS_PER_DOMAIN matapos lang mong bantayan ang iyong 403 rate sa kasalukuyang antas para sa ilang libong request. Ang pag-akyat ng 8 → 32 dahil "nag-ro-rotate naman ang mga proxy" ay kung paano nauubos ng mga tao ang GB sa mga retry.

Bandwidth Discipline (Pera ang Residential GB)

Mga Karaniwang Pagkabigo at Ano Talaga ang Ibig Sabihin Nila

407 Proxy Authentication Required

Hindi nakarating ang credentials sa proxy. Ilagay ang mga ito sa URL (http://user:pass@host:port) sa meta["proxy"] — pina-parse at itinatakda ng Scrapy ang Proxy-Authorization para sa iyo. Ang pagtatakda ng header nang manwal at paggamit ng URL credentials ay nagdudulot ng double-auth na kakaibang asal; pumili ng isa.

TunnelError: Could not open CONNECT tunnel

Halos palaging maling na-type na host/port, o HTTPS target sa pamamagitan ng endpoint na hindi nagpapahintulot ng CONNECT sa port na iyon. I-verify gamit ang curl -x sa labas ng Scrapy muna.

Gumagana ang spider sa loob ng 10 minuto, tapos lahat ay 403

Nabuhay ang iyong sticky session nang lampas sa pagtanggap dito, o sobrang init ng iyong per-domain rate. Hina-handle ng ban-aware middleware sa itaas ang unang kaso; ibaba ang CONCURRENT_REQUESTS_PER_DOMAIN para sa pangalawa. Kung ito ay JA4-checking na target, maaaring ang TLS stack mismo ng Scrapy ang tell — tingnan ang JA3/JA4 explained kung bakit walang proxy ang nag-aayos niyan.

Free tool · no signup

I-validate ang iyong proxy list bago ang crawl

I-paste ang mga endpoint sa aming Proxy Checker: tina-test nito ang connectivity, latency, anonymity level at exit-IP type nang sabay-sabay — mahuli ang mga patay o maling-label na proxy bago sayangin ng Scrapy ang mga retry sa kanila.

Check my proxies →

Pagod sa pagbabantay ng mga libreng listahan? Pinapalitan ng isang residential gateway ang lahat ng iyon — kumuha ng 500MB free traffic →

Buod

Ituro ang Iyong mga Spider sa Totoong Pool

Rotating at sticky residential sessions sa isang gateway. 500MB free traffic para mag-crawl.

Start Free Trial

Para sa lahat ng IP products · napakalaking pool ng nodes na available anumang oras

Magrehistro ngayon at makakuha ng hanggang 100% na rebate sa iyong recharge

Ang mga bagong user ay makakatanggap ng 500MB sa pagrehistro, kasama ang bonus sa unang recharge. Limitadong oras lang ang alok.