خانه/مقالات/اسکریپینگ با FlareSolverr در پایتون
استخراج داده
پروکسی و چرخش IP
ضد بلاک (Anti-bot)
برگشت به مقاله‌ها

اسکریپینگ با FlareSolverr در پایتون

اسکریپینگ با FlareSolverr در پایتون
راهنمای عملی استفاده از FlareSolverr برای عبور از Cloudflare و اسکریپینگ در پایتون: نصب در Docker، نمونه‌های پایتون برای ارسال درخواست، دو الگوی اصلی (ارسال همهٔ درخواست‌ها یا گرفتن کوکی و ادامه با requests)، مدیریت سشن‌ها، نکات امنیتی و جایگزین‌های سبک‌تر یا مدیریت‌شده را پوشش می‌دهد.
آسان اسکریپ آسان اسکریپ
1405-04-31

مقدمه

در این راهنما شما با ابزار متن‌باز FlareSolverr آشنا می‌شوید و یاد می‌گیرید چطور با پایتون از آن برای عبور از محافظت‌های Cloudflare استفاده کنید. هدف عملی این است که بدانید چه زمانی باید کل درخواست‌ها را از طریق یک مرورگر هدلس بفرستید و چه زمانی بهتر است فقط یکبار چالش را پاک کنید، کوکی‌ها و User-Agent را بگیرید و ادامهٔ اسکریپینگ را با Python Requests انجام دهید. در پایان این مطلب مواردی مثل نصب در Docker، مثال‌های پایتون، مدیریت سشن‌ها، POST شدن درخواست‌ها، و گزینه‌های جایگزین را به‌طور دقیق خواهید دید.

نگاهی سریع — ایدهٔ کلی و کاربردها

  • FlareSolverr یک سرور پراکسی HTTP است که Chromium را با undetected-chromedriver اجرا می‌کند تا چالش‌های جاوااسکریپتی و fingerprinting را حل کند.
  • خروجی اصلی: HTML پردازش‌شده و مجموعه‌ای از کوکی‌ها + User-Agent که مرورگر هنگام حل چالش دریافت کرده است.
  • الگوی پیشنهادی: از FlareSolverr برای bootstrap کوکی‌ها استفاده کنید و سپس از یک HTTP client سبک برای ادامهٔ اسکریپینگ استفاده کنید تا هزینه و پیچیدگی عملیاتی کاهش یابد.

نصب و اجرای سریع (Docker)

سریع‌ترین مسیر راه‌اندازی، اجرای کانتینر Docker است. در ادامه دستورات پایه آورده شده‌اند.

# دانلود ایمیج
docker pull flaresolverr/flaresolverr

# اجرای کانتینر (پورت پیش‌فرض 8191)
docker run -d \
  --name=flaresolverr \
  -p 8191:8191 \
  -e LOG_LEVEL=info \
  --restart unless-stopped \
  ghcr.io/flaresolverr/flaresolverr:latest

بعد از اجرا، سرور روی پورت 8191 یک API ساده روی مسیر /v1 ارائه می‌دهد. برای بررسی آماده‌بودن می‌توانید یک درخواست ساده ارسال کنید یا لاگ کانتینر را بررسی کنید.

چگونه FlareSolverr را از پایتون فراخوانی کنیم

ایدهٔ پایه: یک POST با JSON به http://localhost:8191/v1 بفرستید که درونش دستور و URL هدف مشخص شده باشد. پاسخ شامل وضعیت، HTML نهایی و کوکی‌ها خواهد بود.

# نمونه با curl
curl -L -X POST 'http://localhost:8191/v1' \
  -H 'Content-Type: application/json' \
  --data-raw '{"cmd":"request.get","url":"https://www.example.com/","maxTimeout":60000}'

معادل پایتون با requests:

import requests

post_body = {
  'cmd': 'request.get',
  'url': 'https://www.example.com/',
  'maxTimeout': 60000,
}

resp = requests.post('http://localhost:8191/v1', headers={'Content-Type':'application/json'}, json=post_body)
print(resp.status_code)
print(resp.json())

ورودی‌ها: یک دیکشنری JSON شامل cmd و url (و گزینه‌هایی مثل maxTimeout). خروجی: یک JSON که در صورت موفقیت شامل کلید solution است که زیرمجموعه‌هایی مثل cookies، userAgent و response (HTML) را دارد.

گزینهٔ 1 — ارسال همهٔ درخواست‌ها به FlareSolverr

در این حالت هر صفحه‌ای که می‌خواهید اسکریپ کنید را به FlareSolverr می‌دهید و او خودش مرورگر را اجرا می‌کند و جواب را برمی‌گرداند. پیاده‌سازی ساده است ولی معایب عملی دارد:

  • هر درخواست هزینهٔ راه‌اندازی و نگهداری مرورگر را دارد (RAM/CPU بالا).
  • مقیاس‌پذیری محدود و هزینه‌بر است.
  • پایداری کمتر در حجم زیاد و احتمال خطاهای ناشی از محدودیت‌های منابع.
# الگوی ساده: برای هر url یک درخواست به FlareSolverr
import requests

urls = ['https://www.example.com/', 'https://www.example.com/next']
for url in urls:
    post_body = {'cmd':'request.get','url': url, 'maxTimeout':60000}
    r = requests.post('http://localhost:8191/v1', headers={'Content-Type':'application/json'}, json=post_body)
    if r.status_code == 200 and r.json().get('status') == 'ok':
        html = r.json()['solution']['response']
        # ... parse html

جمع‌بندی: خوب برای نمونه‌های کوچک یا حالت‌های ad-hoc، اما در اسکریپینگ حرفه‌ای معمولا گزینهٔ دوم بهتر است.

گزینهٔ 2 — استفاده از FlareSolverr فقط برای گرفتن کوکی معتبر

ایده: از FlareSolverr فقط یک‌بار (یا هر چند وقت یکبار) استفاده کنید تا Cloudflare را حل کند، سپس کوکی‌ها و User-Agent را بردارید و ادامهٔ صفحات را با requests و همان IP/UA انجام دهید. این روش مقرون‌به‌صرفه و مقیاس‌پذیرتر است.

# 1. گرفتن کوکی‌ها از FlareSolverr
import requests

post_body = {'cmd':'request.get','url':'https://www.example.com/','maxTimeout':60000}
r = requests.post('http://localhost:8191/v1', headers={'Content-Type':'application/json'}, json=post_body)
if r.status_code == 200 and r.json().get('status') == 'ok':
    sol = r.json()['solution']
    cookies = sol['cookies']  # لیست کوکی‌ها
    # تبدیل لیست به دیکشنری نام->مقدار برای استفاده با requests
    clean_cookies = {c['name']: c['value'] for c in cookies}
    user_agent = sol['userAgent']

    # 2. استفادهٔ بعدی با requests
    headers = {'User-Agent': user_agent}
    page = requests.get('https://www.example.com/some-page', headers=headers, cookies=clean_cookies)
    if page.status_code == 200:
        # ... parse page.content
        pass

نکات مهم و شرایط موفقیت:

  • کوکی‌های Cloudflare به IP و User-Agent متصل هستند. اگر از IP متفاوت (مثلاً pool پروکسی با روتیشن) استفاده کنید، کوکی‌ها باطل می‌شوند و دوباره چالش خواهید خورد.
  • برای ثبات، یک FlareSolverr session برای هر IP اختصاصی بسازید و درخواست‌های بعدی را با همان IP بزنید.
  • دقت کنید زمان انقضای کوکی‌ها و سیاست‌های سایت را بررسی کنید؛ ممکن است لازم باشد روند گرفتن کوکی را به‌صورت دوره‌ای اجرا کنید.

کنترل سشن‌ها در FlareSolverr

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

# مثال: ایجاد، استفاده و نابود کردن سشن
import requests
API = 'http://localhost:8191/v1'

# ایجاد سشن
r = requests.post(API, json={'cmd':'sessions.create', 'session':'my-session'})
print(r.json())

# استفاده از همان سشن
r = requests.post(API, json={'cmd':'request.get', 'url':'https://www.example.com/', 'session':'my-session', 'maxTimeout':60000})
print(r.json().get('solution', {}).get('status'))

# نابود کردن سشن
requests.post(API, json={'cmd':'sessions.destroy', 'session':'my-session'})

نکتهٔ عملی: سشن‌ها در حافظهٔ کانتینر نگهداری می‌شوند؛ پس اگر کانتینر ری‌استارت شود سشن‌ها پاک می‌شوند. در سرویس‌های طولانی‌مدت، در زمان bootstrap سشن‌ها را بسازید یا مکانیزمی برای بازیابی پیاده کنید.

ارسال درخواست‌های POST از طریق FlareSolverr

اگر نقطهٔ هدف شما یک endpoint با متد POST است (مثلاً لاگین یا فرم‌ها)، باید از request.post و فیلد postData استفاده کنید. postData باید رشته‌ای با فرمت application/x-www-form-urlencoded باشد.

# نمونهٔ POST برای گرفتن کوکی از یک endpoint
import requests
post_body = {
    'cmd':'request.post',
    'url':'https://www.example.com/login',
    'postData':'username=me&password=secret',
    'maxTimeout':60000,
}
r = requests.post('http://localhost:8191/v1', headers={'Content-Type':'application/json'}, json=post_body)
print(r.json())

نکته: اگر API مقصد انتظار JSON دارد، باید آن را قبل از ارسال در قالب x-www-form-urlencoded یا مناسب‌ترین فرم مورد نظر تبدیل کنید؛ FlareSolverr درخواست را داخل مرورگر اجرا می‌کند، پس رفتار فرم‌داده مشابه یک مرورگر واقعی خواهد بود.

مدیریت خطا، Retries و زمان‌بندی

  • همیشه وضعیت HTTP و کلیدهای JSON پاسخ را بررسی کنید و برای حالات خطا Retry کنترل‌شده داشته باشید (exponential backoff).
  • برای درخواست‌های سنگین از maxTimeout استفاده کنید و لاگ‌ها را ضبط کنید تا مواردی که Cloudflare طولانی‌تر از حد معمول پردازش می‌کند را شناسایی کنید.
  • برای افزایش پایداری از مکانیزم‌های صف (job queue) و محدودکننده نرخ (rate limiter) استفاده کنید تا تعداد همزمانی مرورگرها را کنترل کنید.

امنیت و نکات عملیاتی

  • نباید API FlareSolverr را بدون احراز هویت روی اینترنت باز کنید؛ در محیط تولید آن را پشت یک فایروال یا proxy با auth نگه دارید.
  • محدود کردن دسترسی به کانتینر و استفاده از منابع کافی (CPU/RAM) برای اجتناب از کرش مرورگر مهم است.
  • اگر از پروکسی استفاده می‌کنید، به ازای هر IP یک سشن نگه دارید تا کوکی‌ها با IP حل‌کننده یکسان بمانند.

جایگزین‌های عملی (مقایسه و سهم کاربردی)

FlareSolverr عالی است ولی روش‌های دیگری هم وجود دارند که بسته به نیاز شما مناسب‌ترند:

TLS impersonation (کم‌هزینه‌ترین)

اگر تنها مقیاس محافظت سایت بر اساس TLS fingerprinting و HTTP/2 باشد، نیاز به مرورگر کامل ندارید. کتابخانه‌هایی مانند curl_cffi یا افزونه‌هایی برای Scrapy می‌توانند درخواست‌های سطح کانال را طوری بسازند که شبیه مرورگر واقعی به نظر برسند. این روش سرعت و هزینهٔ کمتری دارد ولی در مواجهه با چالش‌های تعاملی جاوااسکریپتی یا Turnstile ناکارا خواهد بود.

درایور جاسازی‌شده (بدون Docker)

کتابخانه‌هایی مانند undetected-chromedriver یا nodriver امکان اجرای تکنیک‌های fortify را درون همان پروسس پایتون به شما می‌دهند. این راه میانه‌ای است بین اجرای جداگانهٔ FlareSolverr و استفاده از مرورگرهای کامل؛ عملیات ساده‌تر است اما هنوز به مدیریت مرورگر نیاز دارید.

پراکسی مدیریت‌شده / Smart Proxy (بدون نگهداری)

اگر نمی‌خواهید به‌روزرسانی‌ها و شکست‌های احتمالی bypass برسید، از سرویس‌های مدیریت‌شدهٔ پراکسی استفاده کنید که bypass را برای شما نگه می‌دارند. این گزینه دردسر عملیاتی را کم می‌کند اما هزینهٔ اشتراک دارد و ممکن است برای پروژه‌های شخصی گران‌تر باشد.

جمع‌بندی

FlareSolverr راهی عملی برای حل چالش‌های Cloudflare با اجرای Chromium است. بهترین الگو برای اسکریپینگ مقیاس‌پذیر این است که از FlareSolverr برای گرفتن کوکی معتبر و User-Agent استفاده کنید و سپس با همان کوکی و UA و IP، ادامهٔ صفحات را با یک HTTP client سبک مثل requests بزنید. نکات عملی کلیدی: سشن‌ها را بر اساس IP مدیریت کنید، مراقب منابع سیستم باشید و مکانیزم‌های retry و rate-limit را پیاده کنید. در نهایت بسته به نوع محافظت سایت (TLS-only، JS challenge، یا Turnstile) ممکن است راه‌حل‌های جایگزین مثل TLS impersonation، درایور جاسازی‌شده یا پراکسی‌های مدیریت‌شده مناسب‌تر باشند.

مطالب مرتبط

مقاله‌های مرتبط