ترکیبهای کلاسیک Selenium و Puppeteer به طور فزایندهای با سیستمهای ضد ربات در سطح Cloudflare، DataDome و PerimeterX مواجه میشوند. فریمورکهای جدیدی مانند Scrapling، Botasaurus و nodriver به وجود آمدهاند که از ابتدا با تمرکز بر دور زدن تشخیص طراحی شدهاند. اما حتی پیشرفتهترین فریمورک نیز بدون پروکسیهای به درستی تنظیم شده بیفایده است. در این مقاله بررسی میکنیم که چگونه پروکسی را در هر یک از این سه ابزار متصل کنیم، چه اشتباهاتی کارایی را از بین میبرد و چگونه نوع IP را برای وظیفه خاص پارسینگ انتخاب کنیم.
تفاوت Scrapling، Botasaurus و nodriver با Selenium
هر سه فریمورک به عنوان پاسخی به این واقعیت که Selenium و Puppeteer معمولی به راحتی قابل شناسایی شدهاند، به وجود آمدند. سیستمهای ضد ربات دهها پارامتر را بررسی میکنند: پروتکل CDP، navigator.webdriver، رندرینگ canvas، زمانبندی رویدادها — و درایورهای کلاسیک تقریباً در هر یک از آنها ردپای مشخصی از خود به جا میگذارند.
Scrapling — یک کتابخانه Python است که پارسینگ HTML را با قابلیت شبیهسازی مرورگر از طریق StealthyFetcher مبتنی بر Camoufox (یک فورک از Firefox با فینگرپرینت پچ شده) ترکیب میکند. این کتابخانه برای وظایفی که به پارسینگ سریع با حداقل مصرف منابع نیاز دارند، مناسب است، اما در عین حال حفاظت سایت به طور فعال TLS-fingerprint را بررسی میکند.
Botasaurus — فریمورکی مبتنی بر Chromium اصلاح شده (undetected-chromedriver در پشت صحنه) است، که برای اسکرپینگ موازی و انبوه با مدیریت خودکار پروفایلهای مرورگر و پشتیبانی داخلی از حل کپچا از طریق سرویسهای خارجی طراحی شده است.
nodriver — جانشین undetected-chromedriver از همان نویسنده است که به طور کامل از Selenium WebDriver صرفنظر کرده و مستقیماً از طریق CDP (پروتکل Chrome DevTools) کار میکند، که بخش قابل توجهی از آثار قابل شناسایی اتوماسیون را حذف میکند.
ویژگی مشترک همه سه فریمورک این است که آنها تشخیص را در سطح فینگرپرینت مرورگر کاهش میدهند، اما مشکل اعتبار IP را حل نمیکنند. اگر درخواستها از یک IP مرکز داده ارسال شوند که قبلاً در لیست سیاه DataDome یا Cloudflare قرار دارد، هیچ پچ مرورگری نمیتواند شما را از کپچا یا خطای 403 نجات دهد.
تنظیم پروکسی در Scrapling
Scrapling از پروکسی هم در حالت HTTP سریع (Fetcher) و هم در حالت مرورگر (StealthyFetcher) پشتیبانی میکند. برای پارسینگ استاتیک بدون رندرینگ JS، پروکسی به طور مستقیم در پارامترهای درخواست منتقل میشود:
from scrapling.fetchers import Fetcher
response = Fetcher.get(
"https://example.com",
proxy="http://user:[email protected]:9000"
)
print(response.status)
برای حالت با مرورگر کامل (StealthyFetcher بر پایه Camoufox) پروکسی از طریق دیکشنری با فیلدهای جداگانه سرور، نام کاربری و رمز عبور منتقل میشود — این مهم است زیرا Camoufox به طور متفاوتی از پروکسی نسبت به Chromium معمولی استفاده میکند:
from scrapling.fetchers import StealthyFetcher
response = StealthyFetcher.fetch(
"https://example.com",
proxy={
"server": "gate.proxycove.com:9000",
"username": "user",
"password": "pass"
},
headless=True
)
print(response.status)
یک اشتباه رایج — ارسال پروکسی به صورت یک رشته کامل در حالت مرورگر، مانند درخواستهای HTTP. در این صورت، Camoufox یا مجوز را نادیده میگیرد یا در مرحله اتصال به سرور پروکسی با زمانگذاری مواجه میشود. اگر خطای ERR_NO_SUPPORTED_PROXIES را مشاهده کردید — فرمت دیکشنری با فیلدهای جداگانه را بررسی کنید.
تنظیم پروکسی در Botasaurus
Botasaurus از دکوراتور @browser
برای پیکربندی درایور استفاده میکند، و پروکسی به عنوان پارامتر این دکوراتور یا به طور مستقیم در تابع راهاندازی منتقل میشود:
from botasaurus.browser import browser, Driver
@browser(
proxy="http://user:[email protected]:9000"
)
def scrape_data(driver: Driver, data):
driver.get("https://example.com")
return driver.page_html
scrape_data()
اگر نیاز به اتصال پروکسیهای مختلف برای هر وظیفه موازی دارید (که در اسکرپینگ انبوه با Botasaurus حیاتی است)، بهتر است پروکسی را به طور دینامیک از طریق لیست دادهها منتقل کنید، نه اینکه در دکوراتور سختافزاری کنید:
from botasaurus.browser import browser, Driver
@browser
def scrape_with_proxy(driver: Driver, data):
driver.config.proxy = data["proxy"]
driver.get(data["url"])
return driver.page_html
tasks = [
{"url": "https://example.com/page1", "proxy": "http://user:pass@ip1:port"},
{"url": "https://example.com/page2", "proxy": "http://user:pass@ip2:port"},
]
scrape_with_proxy(tasks)
Botasaurus به خوبی وظایف را از طریق multiprocessing موازی میکند، بنابراین در اسکرپینگ انبوه مهم است که از پروکسی با مجموعه کافی IP استفاده کنید — در غیر این صورت چندین رشته به یک آدرس یکسان برخورد خواهند کرد که به سرعت اتوماسیون را به الگوی فرکانس درخواستها نشان میدهد.
تنظیم پروکسی در nodriver
nodriver از طریق اتصال مستقیم به CDP بدون لایه Selenium کار میکند، بنابراین پروکسی در اینجا از طریق آرگومانهای راهاندازی مرورگر تنظیم میشود، نه از طریق API جداگانه. برای پروکسی بدون مجوز همه چیز ساده است:
import nodriver as uc
import asyncio
async def main():
browser = await uc.start(
browser_args=["--proxy-server=http://gate.proxycove.com:9000"]
)
page = await browser.get("https://example.com")
await asyncio.sleep(3)
browser.stop()
asyncio.run(main())
مشکل این است که Chromium به طور مستقیم از طریق --proxy-server از نام کاربری/رمز عبور در پروکسی پشتیبانی نمیکند.
برای پروکسیهای مجوزدار در nodriver باید یا یک تونل پروکسی محلی بدون مجوز راهاندازی کنید
(برای مثال، از طریق px یا 3proxy)، یا رویداد CDP را برای Fetch.authRequired پردازش کنید:
import nodriver as uc
import asyncio
async def main():
browser = await uc.start(
browser_args=["--proxy-server=http://gate.proxycove.com:9000"]
)
page = await browser.get("https://example.com")
async def auth_handler(event):
await page.send(uc.cdp.fetch.continue_with_auth(
request_id=event.request_id,
auth_challenge_response=uc.cdp.fetch.AuthChallengeResponse(
response="ProvideCredentials",
username="user",
password="pass"
)
))
page.add_handler(uc.cdp.fetch.AuthRequired, auth_handler)
await asyncio.sleep(5)
browser.stop()
asyncio.run(main())
این نکته یکی از غیرقابل مشاهدهترین موارد در میان همه سه فریمورک است — بسیاری از توسعهدهندگان ساعتها وقت صرف میکنند تا بفهمند چرا مجوز به سادگی کار نمیکند، بدون اینکه از دامنه Fetch در CDP آگاه باشند.
چرخش پروکسی و مبارزه با ضد رباتها
حتی یک فینگرپرینت مرورگر به طور ایدهآل نیز نجاتدهنده نخواهد بود، اگر برای یک IP بیش از 50-100 درخواست در دقیقه به یک دامنه محافظت شده ارسال شود. DataDome و Cloudflare فرکانس درخواستها را از یک آدرس خاص و الگوهای زمانی بین اقدامها تحلیل میکنند — فاصلههای بسیار یکنواخت نیز مشکوک هستند.
طرح کارآمد چرخش برای همه سه فریمورک به طور یکسان ساخته میشود:
- از gateway با چرخش خودکار IP در سطح ارائهدهنده استفاده کنید — نیازی به نوشتن منطق تغییر آدرس برای هر درخواست نیست.
- برای وظایف سسیونی (ورود، ناوبری چند صفحهای) IP را از طریق پارامتر sticky در رشته اتصال ثابت کنید.
- برای پارسینگ ساده صفحات استاتیک، IP را در هر درخواست یا هر 5-10 درخواست بچرخانید.
- بین درخواستها تأخیرهای تصادفی اضافه کنید (1-4 ثانیه) — این کار تشخیص را بر اساس الگوهای زمانی کاهش میدهد.
مثال یک جلسه sticky در رشته اتصال، که session-id یک IP خروجی یکسان را به مدت 10 دقیقه حفظ میکند:
proxy = "http://user-session-abc123:[email protected]:9000"
برای Botasaurus این طرح به ویژه مفید است، زیرا در اسکرپینگ موازی هر فرآیند میتواند session-id منحصر به فرد خود را دریافت کند و شما یک مجموعه پایدار از IPهای مختلف بدون مدیریت دستی لیست آدرسها خواهید داشت.
کدام نوع پروکسی را برای هر فریمورک انتخاب کنیم
نوع پروکسی به اندازه انتخاب فریمورک بر موفقیت پارسینگ تأثیر میگذارد. در زیر مقایسهای بر اساس وظایف آمده است:
| وظیفه | نوع پروکسی پیشنهادی | چرا |
|---|---|---|
| پارسینگ سایتها با Cloudflare/DataDome | پروکسیهای مقیم | IPهای واقعی کاربران خانگی به ندرت در لیست سیاه ضد رباتها قرار میگیرند |
| پارسینگ انبوه بدون حفاظت سخت | پروکسیهای مرکز داده | سرعت بالاتر، هزینه کمتر در حجمهای بالا |
| شبیهسازی کاربر واقعی در سایتهای موبایل | پروکسیهای موبایل | آدرسهای CGNAT اپراتورهای تلفن همراه بالاترین سطح اعتماد را در برابر ضد رباتها دارند |
برای Scrapling در حالت StealthyFetcher، پروکسیهای مقیم بیشترین تأثیر را دارند، زیرا Camoufox قبلاً مشکل فینگرپرینت مرورگر را حل کرده است — تنها چیزی که باقی میماند این است که از نظر IP شناسایی نشوید. برای Botasaurus در اسکرپینگ موازی انبوه، پروکسیهای مرکز داده اغلب از نظر نسبت سرعت/قیمت بهینه هستند، اگر سایت هدف از حفاظت پیشرفتهای مانند DataDome استفاده نکند.
اشتباهات رایج در اتصال پروکسی و اتوماسیون مرورگر
در عمل، بیشتر شکستهای پارسینگ به خود فریمورک مربوط نمیشود، بلکه به پیکربندی نادرست پروکسی مربوط است. در اینجا فهرستی از اشتباهاتی که بیشتر رایج هستند آمده است:
- یکسان بودن IP برای همه رشتههای موازی Botasaurus. ضد ربات 20 جلسه همزمان از یک آدرس را میبیند و در عرض چند دقیقه آن را مسدود میکند.
- انتقال پروکسی به صورت رشتهای در حالت مرورگر Scrapling. Camoufox به دیکشنری با فیلدهای جداگانه نیاز دارد — در غیر این صورت مجوز برقرار نمیشود.
- نادیده گرفتن دامنه CDP Fetch در nodriver. بدون پردازشگر authRequired، پروکسی مجوزدار به سادگی متصل نمیشود و مرورگر در بارگذاری متوقف میشود.
- عدم وجود چرخش در اقدامات سسیونی. تغییر IP در میانه یک جلسه مجوزدار به سرعت اتوماسیون را شناسایی میکند — از جلسات sticky استفاده کنید.
- عدم تطابق جغرافیایی پروکسی و محلی مرورگر. IP از آلمان با هدرهای Accept-Language: ru — نشانه کلاسیک ربات برای سیستمهای امتیازدهی تقلب است.
- فرکانس درخواستها حتی با چرخش بسیار تهاجمی است. چرخش IP نیاز به ایجاد وقفه بین درخواستها را لغو نمیکند — الگوی رفتار نیز تحلیل میشود.
به طور جداگانه باید نشتهای DNS را هنگام کار از طریق پروکسی در حالت مرورگر بررسی کنید — گاهی اوقات مرورگر دامنهها را از طریق DNS سیستم حل میکند، نه از طریق تونل پروکسی، که باعث ایجاد عدم همزمانی بین IP درخواست و IP حل میشود، که به راحتی توسط سیستمهای حفاظتی شناسایی میشود.
نتیجهگیری
Scrapling، Botasaurus و nodriver مشکل تشخیص در سطح فینگرپرینت مرورگر را به مراتب بهتر از Selenium کلاسیک حل میکنند، اما هیچکدام از آنها اهمیت پروکسی با کیفیت را نادیده نمیگیرند. تنظیم صحیح مجوز (به ویژه در nodriver از طریق CDP)، چرخش هوشمند IP و انتخاب نوع مناسب پروکسی برای هر سیستم ضد ربات خاص — سه عاملی هستند که ثبات پارسینگ را در بلندمدت تعیین میکنند.
اگر شما سایتهایی با حفاظت پیشرفته مانند Cloudflare یا DataDome را پارس میکنید، با پروکسیهای مقیم شروع کنید — آنها بالاترین درصد موفقیت درخواستها را به دلیل اعتبار IP ارائه میدهند. برای وظایف انبوه بدون حفاظت سخت پروکسیهای مرکز داده همچنان انتخاب بهینهای از نظر سرعت و هزینه در حجمهای بالا باقی میمانند.