2026 میں بھی Scrapy production crawls کا اصل گھوڑا ہے — اور اب بھی وہی framework ہے جہاں proxy setup لوگوں کو سب سے زیادہ الجھاتا ہے، کیونکہ proxy لگانے کے چار مختلف مقامات ہیں اور ان میں سے تین زیادہ تر projects کے لیے غلط ہیں۔ یہ گائیڈ آپ کو درست والا دیتی ہے: ایک چھوٹا custom middleware جس میں per-request routing، sticky sessions، ban detection اور معقول retry رویہ ہو۔
اگر آپ اس کے بجائے سادہ requests/httpx/aiohttp پر ہیں، تو دیکھیں Python میں Proxies کیسے Rotate کریں۔ یہ مضمون مخصوص طور پر Scrapy کے لیے ہے۔
rotating residential gateway کے لیے کم سے کم قابلِ عمل setup فی request ایک ہی لائن ہے — کسی middleware کی ضرورت نہیں:
def start_requests(self):
for url in self.urls:
yield scrapy.Request(
url,
meta={"proxy": "http://USERNAME:[email protected]:913"},
)
Scrapy کا built-in HttpProxyMiddleware request.meta["proxy"] کو پڑھتا ہے اور URL سے authentication سنبھال لیتا ہے۔ Gateway آپ کے لیے exit IP rotate کرتا ہے۔ اگر آپ کو بس اتنا ہی چاہیے، تو یہیں رک جائیں۔ گائیڈ کا باقی حصہ تب کے لیے ہے جب آپ کو کنٹرول چاہیے: sticky sessions، country routing، ban-aware rotation اور concurrency tuning۔
اسے middlewares.py میں ڈال دیں۔ یہ فی domain sticky sessions تفویض کرتا ہے، bans پر rotate کرتا ہے، اور ہر request کو tag کرتا ہے تاکہ آپ debug کر سکیں کہ کس session نے کیا 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 جو bans کا پتا لگاتا ہے اور تازہ 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)
دونوں کو settings.py میں جوڑیں:
DOWNLOADER_MIDDLEWARES = {
"myproject.middlewares.JibaoProxyMiddleware": 350,
"scrapy.downloadermiddlewares.retry.RetryMiddleware": None, # replace stock retry
"myproject.middlewares.BanAwareRetryMiddleware": 550,
}
RETRY_TIMES = 2
Priority اہم ہے: proxy middleware لازماً Scrapy کے HttpProxyMiddleware (750) سے پہلے چلے، چنانچہ 750 سے کم کوئی بھی قدر چلے گی؛ 350 اسے جلدی اور قابلِ پیش گوئی رکھتا ہے۔
| Crawl کی قسم | Mode | عمل درآمد |
|---|---|---|
| Stateless page harvesting | Rotating | سادہ username، gateway فی request rotate کرتا ہے |
| Login + auth کے پیچھے crawl | Sticky فی account | -session-{account_id}، login کے بیچ کبھی rotate نہ کریں |
| Pagination سے بھرپور listings | Sticky فی domain، ban پر rotate | اوپر والا middleware |
| Geo-مخصوص pricing | Rotating + country pin | USERNAME-country-de طرز کے parameters |
اس trade-off کا گہرا تجزیہ: Sticky بمقابلہ Rotating Proxy Sessions۔
Scrapy کی defaults شائستہ single-IP crawling کے لیے tune کی گئی ہیں۔ rotating pool کے پیچھے آپ کہیں زیادہ زور لگا سکتے ہیں — مگر فی domain حدیں اب بھی اہم ہیں کیونکہ ٹارگٹ مجموعی رویہ دیکھتا ہے:
# 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 کو صرف تب بڑھائیں جب آپ موجودہ سطح پر کئی ہزار requests تک اپنی 403 شرح دیکھ چکے ہوں۔ "proxies تو ویسے بھی rotate ہوتے ہیں" سوچ کر 8 → 32 پر جانا ہی وہ طریقہ ہے جس سے لوگ retries پر GB پھونک دیتے ہیں۔
IMAGES_STORE pipelines کو datacenter proxy یا براہِ راست connection سے fetch کرنے پر سیٹ کریں اگر CDN کو پروا نہ ہو — media آپ کے GB کا بیشتر حصہ ہے اور شاذ و نادر محفوظ ہوتا ہے۔HTTPCACHE_ENABLED = True جب آپ parsers پر کام کر رہے ہوں تو responses کو pool سے دوبارہ fetch کرنے کے بجائے disk سے replay کرتا ہے۔ یہ ایک setting عام طور پر کسی project کا bandwidth bill آدھا کر دیتی ہے۔COMPRESSION_ENABLED = True رکھیں (default) — gzip کی گئی HTML تار پر 5–10 گنا چھوٹی ہوتی ہے۔407 Proxy Authentication RequiredCredentials proxy تک نہیں پہنچیں۔ انہیں meta["proxy"] میں URL کے اندر ڈالیں (http://user:pass@host:port) — Scrapy آپ کے لیے parse کر کے Proxy-Authorization سیٹ کر دیتا ہے۔ header کو دستی طور پر سیٹ کرنا اور ساتھ URL credentials استعمال کرنا double-auth کی الجھن پیدا کرتا ہے؛ ایک کا انتخاب کریں۔
TunnelError: Could not open CONNECT tunnelتقریباً ہمیشہ کسی غلط ٹائپ شدہ host/port کی وجہ سے، یا ایسے endpoint سے HTTPS target جو اس port پر CONNECT کی اجازت نہیں دیتا۔ پہلے Scrapy سے باہر curl -x سے تصدیق کریں۔
آپ کی sticky session اپنی مدت سے زیادہ جی گئی، یا آپ کی فی domain شرح بہت گرم ہے۔ اوپر والا ban-aware middleware پہلے case کو سنبھالتا ہے؛ دوسرے کے لیے CONCURRENT_REQUESTS_PER_DOMAIN کم کریں۔ اگر یہ JA4 جانچنے والا ٹارگٹ ہے، تو خود Scrapy کا TLS stack ہی نشان دہی کر سکتا ہے — دیکھیں JA3/JA4 کی وضاحت کہ کوئی proxy اسے کیوں نہیں ٹھیک کرتا۔
meta["proxy"] ہی پورا setup ہے۔ایک ہی gateway پر rotating اور sticky residential sessions۔ crawl کرنے کے لیے 500MB مفت ٹریفک۔
مفت ٹرائل شروع کریںنئے صارفین کو سائن اپ پر 500MB ملتے ہیں، اس کے علاوہ پہلے ری چارج پر بونس۔ پیشکش محدود وقت کے لیے ہے۔