Scrapy প্রক্সি মিডলওয়্যার: সম্পূর্ণ কনফিগারেশন গাইড (২০২৬)

4 জুন 2026 প্রকাশিত · ≈11 মিনিট পড়া

২০২৬ সালেও Scrapy এখনও প্রোডাকশন ক্রলের প্রধান কর্মী — এবং এখনও সেই ফ্রেমওয়ার্ক যেখানে proxy সেটআপ মানুষকে সবচেয়ে বেশি বিভ্রান্ত করে, কারণ proxy যুক্ত করার চারটি আলাদা জায়গা আছে এবং তার মধ্যে তিনটিই বেশিরভাগ প্রকল্পের জন্য ভুল। এই গাইডটি আপনাকে সঠিকটি দেয়: একটি ছোট কাস্টম middleware যাতে আছে per-request রাউটিং, sticky সেশন, ব্যান শনাক্তকরণ এবং যুক্তিসঙ্গত retry আচরণ।

আপনি যদি এর বদলে সাধারণ requests/httpx/aiohttp ব্যবহার করেন, তাহলে দেখুন Python-এ কীভাবে Proxy ঘোরাবেন। এই নিবন্ধটি Scrapy-নির্দিষ্ট।

৩০-সেকেন্ডের সংস্করণ

একটি rotating residential gateway-এর জন্য, ন্যূনতম কার্যকর সেটআপ হলো প্রতি request-এ এক লাইন — কোনো middleware লাগে না:

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

Scrapy-এর বিল্ট-ইন HttpProxyMiddleware request.meta["proxy"] পড়ে এবং URL থেকে authentication সামলায়। Gateway আপনার জন্য exit IP ঘোরায়। আপনার যদি এটুকুই দরকার হয়, এখানেই থামুন। এই গাইডের বাকি অংশ সেইসব ক্ষেত্রের জন্য যেখানে আপনার নিয়ন্ত্রণ দরকার: sticky সেশন, দেশভিত্তিক রাউটিং, ব্যান-সচেতন rotation এবং concurrency টিউনিং।

একটি প্রোডাকশন Proxy Middleware

এটি আপনার middlewares.py-তে রাখুন। এটি প্রতি ডোমেইনে sticky সেশন বরাদ্দ করে, ব্যানের সময় ঘোরায়, এবং প্রতিটি request ট্যাগ করে যাতে আপনি ডিবাগ করতে পারেন কোন সেশন কী fetch করেছিল:

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()

আর একটি সহযোগী downloader middleware যা ব্যান শনাক্ত করে এবং একটি নতুন সেশনে retry করে:

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)

দুটোই settings.py-তে যুক্ত করুন:

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

অগ্রাধিকার গুরুত্বপূর্ণ: proxy middleware অবশ্যই Scrapy-এর HttpProxyMiddleware (750)-এর আগে চলতে হবে, তাই 750-এর নিচের যেকোনো মান কাজ করে; 350 এটিকে আগেভাগে এবং অনুমেয় রাখে।

Sticky বনাম Rotating: কোন Spider-এর জন্য কোন মোড

ক্রল ধরনমোডবাস্তবায়ন
স্টেটলেস পেজ সংগ্রহRotatingখালি username, gateway প্রতি request-এ ঘোরায়
Login + auth-এর পেছনে ক্রলপ্রতি অ্যাকাউন্টে Sticky-session-{account_id}, login-এর মাঝখানে কখনো ঘোরাবেন না
Pagination-ভারী তালিকাপ্রতি ডোমেইনে Sticky, ব্যানে ঘোরানউপরের middleware
ভৌগোলিক-নির্দিষ্ট মূল্যRotating + দেশ পিনUSERNAME-country-de ধরনের প্যারামিটার

এই ট্রেড-অফের গভীর আলোচনা: Sticky বনাম Rotating Proxy সেশন

Concurrency সেটিংস যা আপনাকে ব্যান করাবে না

Scrapy-এর ডিফল্ট ভদ্রভাবে একক-IP ক্রলের জন্য টিউন করা। একটি rotating পুলের পেছনে আপনি অনেক বেশি চাপ দিতে পারেন — কিন্তু প্রতি-ডোমেইন সীমা এখনও গুরুত্বপূর্ণ কারণ লক্ষ্যবস্তু সামগ্রিক আচরণ দেখে:

# 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

CONCURRENT_REQUESTS_PER_DOMAIN বাড়ান কেবল তখনই যখন আপনি বর্তমান স্তরে কয়েক হাজার request-এর জন্য আপনার 403 হার পর্যবেক্ষণ করেছেন। "proxy তো এমনিতেই ঘোরে" বলে 8 → 32 করা হলো সেই উপায় যেভাবে মানুষ retry-তে GB পুড়িয়ে ফেলে।

Bandwidth শৃঙ্খলা (Residential GB হলো টাকা)

সাধারণ ব্যর্থতা এবং সেগুলো আসলে কী বোঝায়

407 Proxy Authentication Required

Credential proxy পর্যন্ত পৌঁছায়নি। সেগুলো meta["proxy"]-তে URL-এর মধ্যে রাখুন (http://user:pass@host:port) — Scrapy পার্স করে আপনার জন্য Proxy-Authorization সেট করে। হেডার ম্যানুয়ালি সেট করা এবং URL credential ব্যবহার করা দুটোই করলে double-auth অস্বাভাবিকতা ঘটে; একটি বেছে নিন।

TunnelError: Could not open CONNECT tunnel

প্রায় সবসময় host/port-এ টাইপো, অথবা এমন একটি endpoint-এর মাধ্যমে HTTPS লক্ষ্যবস্তু যা সেই port-এ CONNECT অনুমতি দেয় না। প্রথমে Scrapy-এর বাইরে curl -x দিয়ে যাচাই করুন।

Spider ১০ মিনিট কাজ করে, তারপর সবকিছু 403

আপনার sticky সেশন তার স্বাগত মেয়াদ ছাড়িয়ে গেছে, অথবা আপনার প্রতি-ডোমেইন হার অতিরিক্ত গরম। উপরের ব্যান-সচেতন middleware প্রথম ক্ষেত্রটি সামলায়; দ্বিতীয়টির জন্য CONCURRENT_REQUESTS_PER_DOMAIN কমান। যদি এটি একটি JA4-যাচাইকারী লক্ষ্যবস্তু হয়, তবে Scrapy-এর TLS স্ট্যাক নিজেই হয়তো সংকেত দিচ্ছে — কেন কোনো proxy সেটি ঠিক করে না তা জানতে দেখুন JA3/JA4 ব্যাখ্যা

ফ্রি টুল · সাইনআপ নেই

ক্রলের আগে আপনার proxy তালিকা যাচাই করুন

আমাদের Proxy Checker-এ endpoint পেস্ট করুন: এটি একসাথে অনেকগুলোর connectivity, latency, anonymity স্তর এবং exit-IP ধরন পরীক্ষা করে — Scrapy retry-তে সময় নষ্ট করার আগেই মৃত বা ভুল-লেবেলকৃত proxy ধরুন।

আমার proxy পরীক্ষা করুন →

ফ্রি তালিকা সামলাতে ক্লান্ত? একটি residential gateway সব কিছুর বিকল্প — 500MB ফ্রি ট্রাফিক পান →

সারসংক্ষেপ

আপনার Spider-গুলোকে একটি সত্যিকারের পুলের দিকে নির্দেশ করুন

একটি gateway-এ rotating এবং sticky residential সেশন। ক্রল করার জন্য 500MB ফ্রি ট্রাফিক।

ফ্রি ট্রায়াল শুরু করুন

সকল IP পণ্যের জন্য · যেকোনো সময় উপলব্ধ বিশাল নোড পুল

এখনই নিবন্ধন করুন এবং আপনার রিচার্জে ১০০% পর্যন্ত ফেরত পান

নতুন ব্যবহারকারীরা নিবন্ধনের সময় 500MB পান, সাথে প্রথম রিচার্জে বোনাস। সীমিত সময়ের অফার।