FA-TOOLS — Header Component

# کدهای پایتون برای دور زدن captcha در اسکرپ

شاید تو هم مثل من، بارها موقع اسکرپ کردن وبسایت‌های مختلف به دیوار بلند و اعصاب‌خوردکن کپچا خورده باشی. اون لحظه‌ای که بعد از کلی تلاش و تنظیمات، یهو یه کادر “من ربات نیستم” یا یه تصویر مبهم با متن‌های کج و معوج جلوی ران اسکریپتت سبز میشه، واقعاً خسته‌کننده‌ست. اما نگران نباش، این مقاله دقیقاً برای همینه که تو رو از شر این موانع خلاص کنه و بهت نشون بده چطور با پایتون و فریم‌ورک قدرتمند اسکرپ (Scrapy)، از سد کپچاها عبور کنی.

برای دسترسی به مجموعه‌ای بی‌نظیر از ابزارهای برنامه‌نویسی و اسنیپت‌های کاربردی که کار رو برات آب خوردن می‌کنن و بهت کمک می‌کنن تا پروژه‌هات رو سریع‌تر پیش ببری، همین الان به [فروشگاه ابزارها](https://fa-tools.ir/) سر بزن! اونجا کلی [کدهای آماده پایتون](https://fa-tools.ir/snippets/python/) و [اسنیپت‌های کاربردی](https://fa-tools.ir/snippets/) منتظرن تا بهت کمک کنن.

نقشه راه دور زدن کپچا در اسکرپ: یک نگاه سریع 🗺️

این اینفوگرافیک متنی، خلاصه کل مقاله رو بهت نشون میده تا در یک نگاه بفهمی داستان از چه قراره و چطور می‌تونی کپچاها رو دور بزنی:

گام اصلی 🚀 توضیح کوتاه و نکات کلیدی 💡
1. درک مشکل 🚧 چرا کپچا هست؟ (محافظت در برابر بات‌ها). انواع رایج (تصویری، ReCAPTCHA، hCAPTCHA).
2. استراتژی‌های اولیه 🛡️ **کاهش احتمال:** چرخش User-Agent و پراکسی، تاخیرهای تصادفی، مدیریت کوکی‌ها.
3. راه‌حل اصلی: سرویس‌های Anti-CAPTCHA 🤖 مثل 2Captcha, Anti-Captcha. ارسال کپچا، دریافت توکن/جواب. ادغام با Scrapy.
4. مرورگرهای هدلس 🌐 Selenium/Playwright برای کپچاهای JavaScript-محور. انتقال کوکی و سشن به Scrapy.
5. مدیریت خطا و رتری ✅ پیاده‌سازی میدل‌ور برای تشخیص کپچا و تلاش مجدد هوشمندانه.
6. نکات حرفه‌ای و عیب‌یابی 🛠️ اعتبار IP، شبیه‌سازی رفتار انسانی، به‌روزرسانی مداوم. حل مشکلات رایج.

سوال یا کمکی لازم داری؟ با ما در تماس باش: 09202232789

چرا کپچا (CAPTCHA) اینقدر رو اعصابه؟

کپچا، مخفف “Completely Automated Public Turing test to tell Computers and Humans Apart” یه مکانیزم امنیتیه که وبسایت‌ها برای جلوگیری از فعالیت بات‌ها و روبات‌های مخرب ازش استفاده می‌کنن. هدف اصلی کپچا اینه که مطمئن بشه تعامل‌کننده با سایت، یه انسانه، نه یه برنامه کامپیوتری. برای همین، کارهایی رو ازت می‌خواد که انجام دادنشون برای یه انسان راحته، اما برای یه ربات (حداقل بدون تکنیک‌های پیشرفته) سخته.

**انواع رایج کپچا که باهاشون روبرو میشی:**

* **کپچاهای تصویری (Image CAPTCHA):** ازت می‌خواد حروف و اعداد کج و معوج داخل یه تصویر رو وارد کنی.
* **ReCAPTCHA V2 (I’m not a robot):** یه چک‌باکس ساده که پشت پرده کلی تحلیل رفتار کاربر انجام میده. اگه مشکوک بشه، پازل‌های تصویری (انتخاب تصاویر دارای ماشین، چراغ راهنمایی و…) رو نشون میده.
* **ReCAPTCHA V3 (Invisible ReCAPTCHA):** اصلاً چیزی به کاربر نشون نمیده و تو پس‌زمینه بر اساس تعامل کاربر با سایت یه “امتیاز ریسک” میده. اگه امتیاز پایین باشه، یعنی مشکوکی.
* **hCAPTCHA:** یه جایگزین برای ReCAPTCHA، شبیه به ReCAPTCHA V2 عمل می‌کنه و معمولاً پازل‌های تصویری داره.
* **کپچاهای متنی/ریاضی ساده:** مثلاً “حاصل جمع 5 + 3 را وارد کنید”.

برای ما برنامه‌نویسایی که با اسکرپ سروکار داریم، این مکانیزم‌ها مثل یه سد محکم جلوی جمع‌آوری داده‌ها ظاهر میشن. اگه درست مدیریتشون نکنیم، اسکرپرمون رو بلاک می‌کنن یا داده‌های ناقصی برمی‌گردونن.

استراتژی‌های کلی برای مقابله با کپچا در اسکرپ با پایتون

کدهای پایتون برای دور زدن captcha در اسکرپ — تصویر 2

قبل از اینکه بریم سراغ کدهای جدی، یادت باشه که بهترین دفاع، حمله نکردنه! یعنی چی؟ یعنی اول سعی کن طوری رفتار کنی که اصلاً سایت فکر نکنه رباتی و بهت کپچا نشون نده. این خودش یه هنر بزرگه و کلی جلوی دردسرهای بعدی رو می‌گیره.

دور زدن با سرویس‌های Anti-CAPTCHA (رایج‌ترین و موثرترین روش)

اگه تمام تلاش‌هات برای پنهان شدن به نتیجه نرسید و کپچا باز هم بهت حمله کرد، سرویس‌های Anti-CAPTCHA ناجی تو هستن. این سرویس‌ها در واقع یه ارتش از آدم‌های واقعی (یا AI‌های خیلی پیشرفته) هستن که کارشون فقط حل کردن کپچاست. تو کپچا رو بهشون میدی، اونا برات حلش می‌کنن و جواب رو بهت برمی‌گردونن.

**نحوه کار کلی:**

1. اسکرپرت با یه صفحه حاوی کپچا روبرو میشه.
2. به جای اینکه خودش کپچا رو حل کنه، اطلاعات کپچا (مثلاً عکسش یا SiteKey مربوط به ReCAPTCHA) رو به API سرویس Anti-CAPTCHA ارسال می‌کنه.
3. سرویس Anti-CAPTCHA کپچا رو حل می‌کنه و جواب (مثلاً متن داخل عکس یا توکن ReCAPTCHA) رو برمی‌گردونه.
4. اسکرپرت جواب رو به وبسایت مورد نظر ارسال می‌کنه و به کارش ادامه میده.

**مزایا:** دقت بالا، پشتیبانی از انواع کپچا، راحتی پیاده‌سازی.
**معایب:** هزینه‌بر (بر اساس تعداد کپچا), وابستگی به سرویس‌های خارجی، ممکنه کمی زمان‌بر باشه (چند ثانیه تا یک دقیقه).

**مثال‌هایی از سرویس‌های محبوب:** 2Captcha, Anti-Captcha, CapMonster Cloud, XEvil, DeathByCaptcha.

تکنیک‌های پایتون و اسکرپ برای کاهش احتمال مواجهه با کپچا

اینجا چند تا ترفند و تکنیک رو بررسی می‌کنیم که می‌تونی توی اسکرپرت استفاده کنی تا کمتر با کپچا روبرو بشی. یادت باشه، پیشگیری بهتر از درمانه!

1. **چرخش User-Agent:**
هر درخواستی که به وبسایت می‌فرستی، یه User-Agent داره که هویت مرورگر یا اپلیکیشن رو نشون میده. وبسایت‌ها بات‌ها رو اغلب با User-Agentهای ثابت و غیرمرورگر شناسایی می‌کنن. با استفاده از یه لیست بزرگ از User-Agentهای واقعی و چرخوندن اونا، شبیه به مرورگرهای مختلف به نظر میرسی.

“`python
# در فایل settings.py یا داخل یک میدل‌ور
USER_AGENTS = [
‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36’,
‘Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36’,
‘Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0’,
# … لیست طولانی‌تر از User-Agentهای واقعی
]

# در میدل‌ور User-Agent (باید فعالش کنی)
# class RandomUserAgentMiddleware:
# def process_request(self, request, spider):
# request.headers[‘User-Agent’] = random.choice(USER_AGENTS)
“`
برای فعال کردن میدل‌ور می‌تونی به [کدهای آماده و اسنیپت‌های اسکرپ](https://fa-tools.ir/snippets/python/) در سایت ما مراجعه کنی.

2. **چرخش پراکسی (Proxy Rotation):**
مهم‌ترین عامل شناسایی بات‌ها، IP آدرس ثابته. با استفاده از یه لیست از پراکسی‌های معتبر و چرخوندن اونا برای هر درخواست یا هر چند درخواست، اینطور به نظر میاد که درخواست‌ها از IP آدرس‌های مختلف و کاربران متعددی میان.

“`python
# در فایل settings.py
# PROXY_LIST = [
# ‘http://user:pass@proxy1.example.com:8080’,
# ‘http://proxy2.example.com:8080’,
# # … لیست پراکسی‌ها
# ]

# در میدل‌ور Proxy (باید فعالش کنی)
# class ProxyMiddleware:
# def process_request(self, request, spider):
# request.meta[‘proxy’] = random.choice(PROXY_LIST)
“`

3. **مدیریت سشن و کوکی‌ها (Session Management):**
سایت‌ها از کوکی‌ها برای پیگیری فعالیت کاربر استفاده می‌کنن. اگه اسکرپرتت کوکی‌ها رو درست مدیریت نکنه و هر بار با یه سشن جدید ظاهر بشه، مشکوک به نظر میاد. مطمئن شو که اسکرپرتت کوکی‌ها رو برای هر سشن به درستی ذخیره و ارسال می‌کنه. Scrapy به صورت پیش‌فرض این کار رو انجام میده، اما باید مطمئن بشی که غیرفعالش نکرده باشی.

“`python
# در settings.py
# COOKIES_ENABLED = True # مطمئن شو که فعال باشه
“`

4. **تاخیرهای تصادفی (Request Delays and Random Intervals):**
بات‌ها معمولاً درخواست‌ها رو با سرعت ثابت و بالا ارسال می‌کنن. یه کاربر واقعی اینطوری نیست. با اضافه کردن تاخیرهای تصادفی بین درخواست‌ها، رفتار اسکرپرتت رو انسانی‌تر می‌کنی.

“`python
# در settings.py
DOWNLOAD_DELAY = 1.5 # حداقل تاخیر به ثانیه
RANDOMIZE_DOWNLOAD_DELAY = True # فعال کردن تاخیر تصادفی بین 0.5 تا 1.5 برابر DOWNLOAD_DELAY
“`

5. **مرورگرهای هدلس (Headless Browsers با Selenium/Playwright):**
برای وبسایت‌های مدرن که heavily از جاوااسکریپت استفاده می‌کنن، فقط با Scrapy ممکنه به مشکل بربخوری. مرورگرهای هدلس مثل Selenium یا Playwright می‌تونن جاوااسکریپت رو رندر کنن و رفتار یه مرورگر واقعی رو شبیه‌سازی کنن. این روش برای تعامل با کپچاهای جاوااسکریپت‌محور مثل ReCAPTCHA V2 (کلیک روی چک‌باکس) هم کاربرد داره. می‌تونی از این ابزارها برای حل قسمت‌های اولیه کپچا و دریافت کوکی‌های سشن استفاده کنی و بعد ادامه کار رو با Scrapy انجام بدی.

پیاده‌سازی سرویس‌های Anti-CAPTCHA در اسکرپ با پایتون

کدهای پایتون برای دور زدن captcha در اسکرپ — تصویر 3

حالا بیایم یه مثال عملی بزنیم و ببینیم چطور می‌تونیم یه سرویس Anti-CAPTCHA رو با اسکرپ ادغام کنیم. ما اینجا از 2Captcha به عنوان مثال استفاده می‌کنیم، چون یکی از معروف‌ترین‌ها و پرکاربردترین‌هاست.

**قدم اول: ثبت‌نام و دریافت API Key**
باید بری توی سایت 2Captcha (یا هر سرویس مشابهی)، ثبت‌نام کنی، مقداری شارژش کنی و API Key خودت رو بگیری. این کلید برای احراز هویت درخواست‌های تو استفاده میشه.

**قدم دوم: نصب کتابخانه 2Captcha (در صورت نیاز)**
بعضی سرویس‌ها کتابخانه پایتون دارن که کار رو راحت‌تر می‌کنه. برای 2Captcha می‌تونی `2captcha-python` رو نصب کنی:

“`bash
pip install 2captcha-python
“`

**قدم سوم: پیاده‌سازی در اسکرپ**

فرض کن ما با یه فرم لاگین روبرو هستیم که یه ReCAPTCHA V2 داره. مراحل کار به این صورته:

1. درخواست اولیه به صفحه لاگین می‌فرستیم تا `sitekey` کپچا و سایر اطلاعات فرم رو بگیریم.
2. `sitekey` رو به سرویس 2Captcha می‌فرستیم.
3. منتظر می‌مونیم تا 2Captcha توکن حل‌شده رو بهمون بده.
4. با توکن دریافتی و سایر اطلاعات فرم، درخواست لاگین نهایی رو می‌فرستیم.

“`python
import scrapy
import json
import time
from twocaptcha import TwoCaptcha

# تنظیمات 2Captcha
# حتماً API Key خودت رو اینجا جایگزین کن
SOLVER_API_KEY = ‘YOUR_2CAPTCHA_API_KEY’
solver = TwoCaptcha(SOLVER_API_KEY)

class CaptchaBypassSpider(scrapy.Spider):
name = ‘captcha_bypass’
start_urls = [‘http://example.com/login-with-captcha’] # آدرس صفحه لاگین با کپچا

def parse(self, response):
# 1. اطلاعات سایت‌کی و سایر فیلدهای فرم رو پیدا کن
site_key = response.css(‘div.g-recaptcha::attr(data-sitekey)’).get()
if not site_key:
self.logger.error(“Site Key for reCAPTCHA not found!”)
return

# فرض می‌کنیم اینجا سایر فیلدهای فرم رو هم داریم
# مثلاً token CSRF, username, password
# اینها رو باید از response استخراج کنی

# 2. کپچا رو به 2Captcha بفرست
self.logger.info(f”Solving reCAPTCHA with sitekey: {site_key}”)

try:
# اینجا ممکنه بسته به نوع کپچا متفاوت باشه
# برای ReCAPTCHA V2 از method=’captcha’ استفاده می‌کنیم و url صفحه فعلی رو هم میدیم
result = solver.recaptcha(sitekey=site_key, url=response.url)
captcha_token = result[‘code’]
self.logger.info(f”CAPTCHA solved! Token: {captcha_token[:30]}…”) # نمایش بخشی از توکن

# 3. با توکن دریافتی، فرم رو سابمیت کن
# این قسمت بسته به ساختار فرم وبسایت مقصد متفاوته
form_data = {
‘username’: ‘your_username’,
‘password’: ‘your_password’,
‘g-recaptcha-response’: captcha_token # توکن کپچا
# سایر فیلدهای فرم
}
yield scrapy.FormRequest(
url=response.url, # معمولاً به همون آدرس POST میشه
formdata=form_data,
callback=self.after_login
)

except Exception as e:
self.logger.error(f”Error solving CAPTCHA: {e}”)
# اینجا می‌تونی درخواست رو رتری کنی یا به حالت خطا بری
# مثلاً yield response.request.copy()
# یا yield scrapy.Request(url=response.url, callback=self.parse, dont_filter=True)

def after_login(self, response):
# اینجا می‌تونی بررسی کنی که لاگین موفق بوده یا نه
if “Welcome” in response.text: # مثال: بررسی یه متن در صفحه بعد از لاگین
self.logger.info(“Login successful!”)
# ادامه اسکرپینگ
else:
self.logger.warning(“Login failed, possibly due to CAPTCHA or incorrect credentials.”)
# شاید بخوای دوباره تلاش کنی یا با پراکسی دیگه امتحان کنی
“`

**نکته:** برای کپچاهای تصویری (Image CAPTCHA)، باید عکس کپچا رو از صفحه استخراج کنی و به جای `solver.recaptcha` از `solver.normal` استفاده کنی و تصویر رو به صورت `base64` یا `path` ارسال کنی.

ترفند برنامه‌نویسی:

همیشه API Key رو در کد به صورت Hardcode نذار! از متغیرهای محیطی (Environment Variables) استفاده کن تا امنیتش بیشتر باشه. مثلاً os.environ.get('2CAPTCHA_API_KEY').

مزایا و معایب استفاده از سرویس‌های Anti-CAPTCHA

استفاده از این سرویس‌ها، مثل هر ابزار دیگه‌ای، نقاط قوت و ضعف خودش رو داره که باید بدونی.

مزایا 👍 معایب 👎
**دقت بالا:** نرخ موفقیت حل کپچا معمولاً بالای 90% است. **هزینه‌بر:** باید به ازای هر کپچای حل شده هزینه کنی.
**پشتیبانی گسترده:** انواع کپچاها (ReCAPTCHA, hCAPTCHA, تصویری) را پوشش می‌دهند. **تاخیر:** زمان لازم برای حل کپچا توسط سرویس (چند ثانیه تا یک دقیقه).
**سادگی پیاده‌سازی:** اغلب دارای SDK و APIهای ساده هستند. **وابستگی خارجی:** عملکرد اسکرپر به در دسترس بودن و پایداری سرویس بستگی دارد.
**عدم نیاز به دانش AI:** لازم نیست خودت مکانیزم حل کپچا رو بفهمی. **ریسک شناسایی:** اگرچه کم، اما سرویس‌های کپچا دائماً در حال به‌روزرسانی هستند.

ترکیب اسکرپ با مرورگرهای هدلس (Headless Browsers) برای کپچاهای پیچیده‌تر

بعضی وقت‌ها، کپچاها اونقدر پیچیده‌ان یا سایت اونقدر از جاوااسکریپت برای بارگذاری دینامیک محتوا استفاده می‌کنه که سرویس‌های Anti-CAPTCHA هم به تنهایی کافی نیستن. اینجا پای مرورگرهای هدلس مثل Selenium یا Playwright به میون میاد.

استفاده از Selenium و Playwright

این ابزارها مرورگرهای واقعی هستن که بدون UI (رابط کاربری) کار می‌کنن. یعنی تمام جاوااسکریپت‌ها رو اجرا می‌کنن، کوکی‌ها رو مدیریت می‌کنن و حتی می‌تونن کلیک کنن یا فرم‌ها رو پر کنن، دقیقاً مثل یه کاربر واقعی.

**کی ازشون استفاده کنیم؟**

* وقتی سایت به شدت به جاوااسکریپت وابسته است.
* برای حل ReCAPTCHA V2 (اون چک‌باکس “من ربات نیستم”) که نیاز به کلیک و شاید حل پازل‌های تصویری داره.
* وقتی می‌خوای سشن (Session) و کوکی‌های یه مرورگر واقعی رو به Scrapy منتقل کنی.

**ادغام با Scrapy:**

ایده اینه که از مرورگر هدلس برای بازدید اولیه از صفحه، حل کپچا (اگه کپچا قابل حل باشه) و جمع‌آوری کوکی‌های سشن استفاده کنی. بعد از اینکه این کارها انجام شد، کوکی‌ها رو به درخواست‌های Scrapy منتقل می‌کنی تا اسکرپرت بتونه به کارش ادامه بده.

“`python
from scrapy import Request
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
import time
import json # برای ذخیره کوکی‌ها

# فرض می‌کنیم توکن 2Captcha رو از قبل با روش قبلی حل کردیم یا اصلا کپچا رو مرورگر حل کرده.
# این مثال بیشتر روی انتقال سشن تمرکز داره.

class HeadlessBrowserSpider(scrapy.Spider):
name = ‘headless_spider’
start_urls = [‘http://example.com/site-with-complex-js’]

def __init__(self, *args, **kwargs):
super(HeadlessBrowserSpider, self).__init__(*args, **kwargs)
# تنظیمات برای مرورگر هدلس (مثلاً کروم)
chrome_options = Options()
chrome_options.add_argument(“–headless”) # حالت هدلس
chrome_options.add_argument(“–no-sandbox”)
chrome_options.add_argument(“–disable-dev-shm-usage”)
chrome_options.add_argument(“user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36”)

# استفاده از webdriver_manager برای دانلود خودکار درایور کروم
self.driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options)

def start_requests(self):
# 1. با مرورگر هدلس به صفحه برو
self.logger.info(“Starting headless browser to get initial cookies…”)
self.driver.get(self.start_urls[0])
time.sleep(5) # صبر کن تا جاوااسکریپت‌ها کامل بارگذاری بشن و احتمالا کپچا حل بشه

# 2. کوکی‌ها رو از مرورگر استخراج کن
cookies = self.driver.get_cookies()

# 3. مرورگر رو ببند (دیگه بهش نیاز نداریم)
self.driver.quit()
self.logger.info(“Headless browser closed. Proceeding with Scrapy.”)

# 4. کوکی‌ها رو برای Scrapy آماده کن
scrapy_cookies = {c[‘name’]: c[‘value’] for c in cookies}

# 5. درخواست رو با کوکی‌های دریافتی از مرورگر هدلس بفرست
yield Request(
url=self.start_urls[0],
cookies=scrapy_cookies,
callback=self.parse_page_with_cookies
)

def parse_page_with_cookies(self, response):
self.logger.info(f”Received response with cookies for URL: {response.url}”)
# اینجا می‌تونی محتوای صفحه رو پارس کنی
# مطمئناً الان دیگه کپچا نباید ظاهر بشه چون سشن معتبر داری
title = response.css(‘title::text’).get()
self.logger.info(f”Page title: {title}”)

# مثلاً استخراج لینک‌های دیگه
for link in response.css(‘a::attr(href)’).getall():
if link.startswith(‘http’):
yield response.follow(link, callback=self.parse_other_pages, cookies=response.request.cookies) # کوکی‌ها رو هم انتقال بده

def parse_other_pages(self, response):
self.logger.info(f”Parsing other page: {response.url}”)
# ادامه اسکرپینگ
“`

این کد یه چارچوب کلی برای ادغام Selenium با Scrapy نشون میده. در سناریوهای واقعی، حل کپچا با Selenium ممکنه پیچیده‌تر باشه و نیاز به تشخیص المان‌های کپچا و کلیک روی اون‌ها (در ReCAPTCHA V2) یا حتی وارد کردن جواب حل شده توسط یه سرویس Anti-CAPTCHA در فیلد مربوطه داشته باشه.

مدیریت خطاهای کپچا و رتری (Retry) در اسکرپ

وقتی با کپچا دست و پنجه نرم می‌کنی، احتمال خطا بالاست. ممکنه سرویس Anti-CAPTCHA جواب نده، توکن اشتباه باشه، یا خود سایت به دلایلی (حتی با جواب صحیح) کپچا رو رد نکنه. اینجا مدیریت خطا و سیستم رتری (تلاش مجدد) هوشمندانه خیلی مهمه.

**میدل‌ور تشخیص کپچا:**
بهترین راه، ساخت یه میدل‌ور (Middleware) سفارشیه که بعد از هر درخواست، پاسخ دریافتی رو بررسی کنه تا ببینه آیا کپچا ظاهر شده یا نه.

“`python
import logging
import random
from scrapy.downloadermiddlewares.retry import RetryMiddleware
from scrapy.utils.response import get_meta_refresh

logger = logging.getLogger(__name__)

class CaptchaRetryMiddleware(RetryMiddleware):
# این میدل‌ور باید بعد از HttpProxyMiddleware و RandomUserAgentMiddleware فعال بشه.

def process_response(self, request, response, spider):
if self.should_retry(response, request):
reason = self._get_retry_request_reason(response)
return self._retry(request, reason, spider)
return response

def should_retry(self, response, request):
# بررسی می‌کنیم که آیا صفحه شامل المان‌های رایج کپچا هست یا نه
captcha_indicators = [
‘I’m not a robot’,
‘g-recaptcha’,
‘h-captcha’,
‘/captcha.php’, # مسیرهای رایج فایل کپچا
‘Please verify you are human’,
‘Solve the puzzle’
]

# می‌تونیم از CSS selectors یا regex هم استفاده کنیم
# مثال: بررسی وجود تگ div با کلاس g-recaptcha
if response.css(‘div.g-recaptcha’).get() or response.css(‘div.h-captcha’).get():
logger.warning(f”CAPTCHA detected on {response.url}, retrying…”)
return True

for indicator in captcha_indicators:
if indicator.lower() in response.text.lower():
logger.warning(f”CAPTCHA indicator ‘{indicator}’ detected on {response.url}, retrying…”)
return True

# اگه کد وضعیت HTTP 403 یا 429 باشه (Forbidden / Too Many Requests) هم ممکنه به خاطر کپچا باشه
if response.status in [403, 429]:
logger.warning(f”HTTP Status {response.status} detected on {response.url}, retrying…”)
return True

return False

def _retry(self, request, reason, spider):
retries = request.meta.get(‘retry_times’, 0) + 1
max_retries = self.max_retry_times

if retries <= max_retries:
logger.debug(f"Retrying {request.url} (failed {retries}/{max_retries} times): {reason}")
retryreq = request.copy()
retryreq.meta['retry_times'] = retries
retryreq.dont_filter = True # برای اینکه دوباره همین URL رو دانلود کنه

# اینجا می‌تونی منطق حل کپچا رو فعال کنی یا پراکسی عوض کنی
# مثلاً: if 'captcha_solved' not in retryreq.meta:
# retryreq.meta['solve_captcha'] = True

# تاخیر تصادفی برای تلاش مجدد
retryreq.meta['download_timeout'] = self.retry_http_codes
time.sleep(random.uniform(self.retry_delay, self.retry_delay * 2))
return retryreq
else:
logger.error(f"Gave up retrying {request.url} (failed {retries} times): {reason}")
spider.crawler.stats.inc_value(f'retry/max_retries_exceeded')
return None # یا آیتم رو به عنوان خطا برگردون
“`
بعد از نوشتن این میدل‌ور، باید اون رو توی فایل `settings.py` فعال کنی و ترتیبش رو هم تنظیم کنی:

“`python
# settings.py
DOWNLOADER_MIDDLEWARES = {
# … سایر میدل‌ورها
'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None, # دی‌اکتیو کردن میدل‌ور پیش‌فرض
'your_project_name.middlewares.RandomUserAgentMiddleware': 400, # میدل‌ور چرخش User-Agent خودت
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': None, # دی‌اکتیو کردن پیش‌فرض
'your_project_name.middlewares.ProxyMiddleware': 410, # میدل‌ور چرخش پراکسی خودت
'your_project_name.middlewares.CaptchaRetryMiddleware': 500, # میدل‌ور تشخیص و رتری کپچا
'scrapy.downloadermiddlewares.retry.RetryMiddleware': None, # دی‌اکتیو کردن میدل‌ور رتری پیش‌فرض
}

RETRY_ENABLED = False # چون میدل‌ور رتری خودمون رو داریم
#RETRY_TIMES = 3 # تعداد دفعات مجاز برای تلاش مجدد در میدل‌ور خودمون
#RETRY_HTTP_CODES = [500, 502, 503, 504, 522, 524, 408, 403, 429] # کدهای خطایی که می‌خوایم رتری بشن
#RETRY_DELAY = 10 # حداقل تاخیر برای رتری
“`

نکته امنیتی:

در میدل‌ور `CaptchaRetryMiddleware`، وقتی تشخیص کپچا میدی و `retryreq` رو برمی‌گردونی، می‌تونی `meta` درخواست رو آپدیت کنی و مثلاً یه `flag` بذاری که نشون بده این درخواست نیاز به حل کپچا داره. بعد توی میدل‌ور `download_process` می‌تونی این `flag` رو چک کنی و منطق حل کپچا با 2Captcha رو اونجا اجرا کنی. اینطوری کد منظم‌تر میشه و مسئولیت‌ها تقسیم میشن.

نکات حرفه‌ای برای افزایش موفقیت در دور زدن کپچا

برای اینکه واقعاً یه برنامه‌نویس حرفه‌ای باشی و اسکرپرتت کمترین مشکل رو با کپچا داشته باشه، باید به چند نکته ظریف اما حیاتی توجه کنی:

1. **مدیریت اعتبار IP (IP Reputation Management):**
سایت‌ها IPهایی رو که قبلاً مشکوک بودن یا درخواست‌های زیادی ازشون اومده رو به عنوان “Bad Reputation” علامت‌گذاری می‌کنن. استفاده از پراکسی‌های باکیفیت و چرخش منظم اون‌ها (به ویژه Residential Proxies که IPهای کاربران واقعی هستن) می‌تونه اعتبار IP تو رو بالا نگه داره. از IPهای Shared و Free Proxyها تا حد ممکن دوری کن.

2. **شبیه‌سازی رفتار انسانی (Human-like Behavior Simulation):**
فقط تغییر User-Agent و پراکسی کافی نیست. سرعت کلیک‌ها، حرکت موس، زمان ماندن در صفحه، اسکرول کردن، پر کردن فیلدها با تاخیرهای طبیعی، همه اینها در تشخیص بات تاثیر دارن. مرورگرهای هدلس و کتابخانه‌هایی مثل `fake-useragent` و `requests-toolbelt` می‌تونن کمک کنن.

3. **مانیتورینگ نرخ موفقیت (Monitoring Success Rates):**
اسکرپرتت رو مانیتور کن. چند درصد از کپچاها با موفقیت حل میشن؟ آیا نرخ بلاک شدن افزایش پیدا کرده؟ با رصد این متریک‌ها می‌تونی به موقع مشکلات رو تشخیص بدی و استراتژیت رو تغییر بدی.

4. **همیشه به‌روز باش (Staying Updated):**
مکانیزم‌های کپچا دائم در حال تکامل هستن. ReCAPTCHA V2 و V3، hCAPTCHA، Arkose Labs و… هر روز هوشمندتر میشن. باید همیشه در جریان آخرین تغییرات باشی و روش‌هات رو به‌روز کنی.

5. **سلف-سولوینگ کپچاهای ساده (Self-solving Simple CAPTCHAs):**
برای کپچاهای تصویری خیلی ساده و ثابت (مثلاً جمع و تفریق ساده یا تشخیص حروف واضح)، ممکنه بتونی با کتابخانه‌های پردازش تصویر پایتون مثل OpenCV و Tesseract OCR خودت یه سلف-سولور ساده بنویسی. این کار هزینه سرویس‌های Anti-CAPTCHA رو کاهش میده. اما برای کپچاهای پیچیده و مدرن، این روش معمولاً کارساز نیست و باید به سرویس‌های تخصصی اعتماد کنی. **توجه:** برای کپچاهای تصویری با فونت‌های پیچیده یا نویز زیاد، نوشتن سولور کار راحتی نیست و نیاز به دانش یادگیری ماشین و شبکه‌های عصبی (مثل CNN) داره. این یه کار متخصصانه و وقت‌گیره.

عیب‌یابی سریع: مشکلات رایج در دور زدن کپچا و راه‌حل‌ها

تو این بخش، به مشکلات رایجی که ممکنه موقع دور زدن کپچا در اسکرپ بهش بربخوری، می‌پردازیم و راه‌حل‌های عملی براشون ارائه میدیم.

1. **مشکل: “کپچا هنوز ظاهر میشه، حتی با پراکسی و User-Agent چرخشی!”**
* **راه‌حل:**
* **کیفیت پراکسی:** از پراکسی‌های باکیفیت‌تر (مثل Residential Proxies) استفاده کن. IPهای Shared/Datacenter خیلی سریع بلاک میشن.
* **تعداد User-Agent:** لیست User-Agentهات رو بزرگ‌تر و متنوع‌تر کن.
* **تاخیرها:** `DOWNLOAD_DELAY` و `RANDOMIZE_DOWNLOAD_DELAY` رو افزایش بده و مطمئن شو که واقعاً تاخیر مناسبی بین درخواست‌ها ایجاد میشه.
* **مدیریت کوکی:** مطمئن شو که `COOKIES_ENABLED` در `settings.py` فعاله و کوکی‌ها به درستی برای هر سشن مدیریت میشن. گاهی اوقات نیاز به پاک کردن کوکی‌ها برای هر درخواست جدید داری.
* **Headerهای دیگر:** بعضی سایت‌ها به `Accept-Language`, `Referer`, `Cache-Control` و سایر هدرها هم اهمیت میدن. سعی کن اون‌ها رو هم شبیه‌سازی کنی.
* **User-Agent ثابت:** بعضی از سایت‌ها از User-Agentهای معروف مرورگرها که قدیمی شده‌اند، برای شناسایی استفاده می‌کنند.

2. **مشکل: “سرویس Anti-CAPTCHA درست جواب نمیده یا خطا میده!”**
* **راه‌حل:**
* **API Key:** مطمئن شو که API Key رو درست وارد کردی و حسابت شارژ داره.
* **نوع کپچا:** چک کن که نوع کپچایی که به سرویس میفرستی (مثلاً `recaptcha`، `normal`، `hcaptcha`) با نوع کپچای واقعی در صفحه مطابقت داشته باشه.
* **SiteKey/Image:** برای ReCAPTCHA/hCAPTCHA، `sitekey` رو درست از صفحه استخراج کردی؟ برای کپچاهای تصویری، آیا تصویر کپچا رو به درستی Base64 کردی و فرستادی؟
* **URL صفحه:** برای ReCAPTCHA، حتماً `url` صفحه‌ای که کپچا روش هست رو هم به سرویس بفرست.
* **Timeout:** گاهی اوقات سرویس Anti-CAPTCHA ممکنه زمان بیشتری برای حل نیاز داشته باشه. `timeout` رو در درخواست به سرویس افزایش بده.
* **وضعیت سرویس:** ممکنه خود سرویس Anti-CAPTCHA دچار مشکل فنی شده باشه. وضعیت سرویس (System Status) رو چک کن.

3. **مشکل: “سایت منو بلاک میکنه، حتی بعد از حل کپچا و لاگین موفق!”**
* **راه‌حل:**
* **ردپای جاوااسکریپت (JS Fingerprinting):** حتی اگه کوکی و User-Agent رو درست کنی، سایت‌ها می‌تونن از اثر انگشت‌گیری جاوااسکریپت (Canvas Fingerprinting, WebGL Fingerprinting و…) برای شناسایی بات‌ها استفاده کنن. برای این موارد، استفاده از مرورگرهای هدلس مثل Playwright (که قابلیت‌های ضد تشخیص قوی‌تری داره) یا **Selenium Stealth** می‌تونه مفید باشه.
* **رفتار پس از حل:** آیا بعد از حل کپچا، باز هم با سرعت زیادی درخواست میفرستی؟ بعد از حل کپچا و لاگین، با تاخیرهای طبیعی (مثلاً 5 تا 10 ثانیه) به کار ادامه بده.
* **Cookies/Session Persistence:** مطمئن شو که کوکی‌های سشن به درستی در تمام درخواست‌های بعدی ارسال میشن. اگه کوکی‌ها پاک بشن یا تغییر کنن، سایت دوباره مشکوک میشه.
* **هدرها:** هدرهای `Accept`, `Accept-Encoding`, `Connection` و `Origin` رو مثل یه مرورگر واقعی تنظیم کن.

4. **مشکل: “اسکرپرم خیلی کُنده وقتی از سرویس‌های Anti-CAPTCHA استفاده میکنم.”**
* **راه‌حل:**
* **Parallelization:** اسکرپرت رو به صورتی طراحی کن که بتونه چند کپچا رو همزمان برای سرویس Anti-CAPTCHA ارسال کنه (با استفاده از `Deferred` در Scrapy یا `asyncio` در پایتون).
* **Priority Queue:** درخواست‌هایی که نیاز به حل کپچا دارن رو در یه صف با اولویت بالاتر قرار بده تا زودتر پردازش بشن، اما بدون آسیب زدن به نرخ بلاک شدن.
* **Caching:** اگه کپچاهای مشابهی رو بارها می‌بینی، شاید بتونی جوابشون رو برای مدت کوتاهی کش (Cache) کنی. (البته این مورد برای ReCAPTCHA V2/V3 کاربرد نداره و معمولا جواب هر کپچا یکبار مصرف است.)

سوالات متداول (FAQ)

آیا دور زدن کپچا قانونیه؟

این سوال پیچیده‌ایه و پاسخ سرراستی نداره. از نظر فنی، دور زدن کپچا لزوماً غیرقانونی نیست. اما نکته اینجاست که هدف سایت از گذاشتن کپچا، جلوگیری از دسترسی خودکار به اطلاعاته. اگر با این کار قوانین و مقررات سایت (Terms of Service) رو نقض کنی، یا به حریم خصوصی افراد تجاوز کنی، یا سوءاستفاده‌ای انجام بدی، اون موقع ممکنه با مشکلات حقوقی روبرو بشی. همیشه قبل از اسکرپ کردن هر سایتی، حتماً TOS اون رو بخون و در چارچوب قوانین و اخلاق فعالیت کن. ما به هیچ عنوان استفاده غیراخلاقی یا غیرقانونی از این کدها رو تأیید نمی‌کنیم.

کدوم سرویس Anti-CAPTCHA بهترینه؟

“بهترین” سرویس به نیازها و بودجه تو بستگی داره. 2Captcha و Anti-Captcha معمولاً نرخ موفقیت بالا و پشتیبانی خوبی دارن و قیمت مناسبی هم دارند. DeathByCaptcha هم گزینه‌ی خوبی برای مقیاس‌های بزرگ‌تره. CapMonster Cloud یه گزینه خوب برای کسایی که به دنبال راه‌حل‌های سریع‌تر و بعضاً محلی (با نصب نرم‌افزار) هستند. بهترین کار اینه که چند مورد رو امتحان کنی و ببینی کدوم یکی برای پروژه‌های تو بهتر جواب میده. برای اینکه تصمیم بگیری، فاکتورهایی مثل قیمت، سرعت حل، پشتیبانی از انواع کپچا و نرخ موفقیت حل رو در نظر بگیر.

آیا میتونم سولور (Solver) کپچای خودم رو بسازم؟

برای کپچاهای خیلی ساده و قدیمی (مثل تصاویر با حروف واضح و بدون نویز زیاد)، بله، میشه با استفاده از کتابخانه‌های پردازش تصویر مثل OpenCV و OCR (مثلاً Tesseract) یه سولور ساده ساخت. اما برای کپچاهای مدرن‌تر مثل ReCAPTCHA، hCAPTCHA یا کپچاهای تصویری با نویز و دست‌کاری زیاد، ساخت یه سولور خودت از صفر کار فوق‌العاده پیچیده و زمان‌بریه که نیاز به دانش عمیق در یادگیری ماشین و شبکه‌های عصبی داره و معمولاً هزینه و زمانش از استفاده از سرویس‌های آماده بیشتر در می‌آید. توصیه میشه برای این مدل کپچاها، از سرویس‌های تخصصی استفاده کنی.

سخن پایانی

دور زدن کپچا در اسکرپ یکی از چالش‌های بزرگ و البته جدایی ناپذیر در دنیای وب اسکرپینگه. همونطور که دیدی، رویکردهای مختلفی برای مقابله باهاش وجود داره: از پیشگیری (با رفتار انسانی) گرفته تا درمان (با سرویس‌های Anti-CAPTCHA و مرورگرهای هدلس). مهم اینه که یه استراتژی چندوجهی داشته باشی و از ترکیب این روش‌ها به صورت هوشمندانه استفاده کنی.

یادت باشه، همیشه بهینه سازی و آپدیت کردن اسکرپرتت یه فرآیند پیوسته است. هرچه بیشتر با قوانین نانوشته وب تعامل کنی و واکنش سایت‌ها رو ببینی، ماهرتر میشی. با استفاده از [کدهای آماده و اسنیپت‌های پایتون ما](https://fa-tools.ir/snippets/python/) و تمرین مداوم، می‌تونی تقریباً از هر سدی عبور کنی و داده‌های مورد نظرت رو جمع‌آوری کنی. موفق باشی رفیق برنامه‌نویس!

Table of Contents

آخرین نوشته‌ها