مقدمه
در این راهنمای عملی میخوانید چگونه با ابزار Playwright بهصورت قابل اتکا سایتهایی که پشت محافظت Cloudflare قرار دارند را اسکریپ کنید. هدف این مطلب این است که علاوه بر توضیح مکانیزمهای تشخیص Cloudflare، چند روش عملی (از ساده تا پیشرفته) همراه با مثالهای کد — عمدتاً برای توسعهدهندههای پایتون — ارائه دهیم تا پس از خواندن بتوانید تصمیم بگیرید کدام روش برای سناریوی شما مناسب است.
در پایان مطالب زیر را یاد میگیرید: مفهوم چالشهای Cloudflare، روشهای کارساز برای عبور از آن با Playwright، نمونههای کد پایتون (و نکاتی درباره استفاده از پراکسی و پلاگینها)، و بهترین روشهای امنیتی و عملی برای پایداری اسکریپها.
TLDR: نمونهی سریع (پایتون) با پراکسی
در یک سناریوی ساده، میتوان با تنظیم پراکسی هنگام راهاندازی Playwright از تشخیص مستقیم IP جلوگیری کرد. مثال زیر از API پراکسی (مثل ScrapeOps) استفاده میکند. این مثال با playwright.async_api نوشته شده است.
from playwright.async_api import async_playwright
PROXY_SERVER = "http://residential-proxy.scrapeops.io:8181"
PROXY_USERNAME = "scrapeops"
PROXY_PASSWORD = "YOUR-SCRAPEOPS-RESIDENTIAL-PROXY-API-KEY"
async def main():
async with async_playwright() as p:
browser = await p.chromium.launch(proxy={
"server": PROXY_SERVER,
"username": PROXY_USERNAME,
"password": PROXY_PASSWORD
}, headless=True)
page = await browser.new_page()
await page.goto("https://whatismybrowser.com")
await page.wait_for_timeout(4000)
await browser.close()
# اجرا: از یک حلقهی async استفاده کنید یا در اسکریپت اصلی فراخوانی کنید
توضیح ورودی/خروجی و نقشها:
- PROXY_*: مشخصکنندهی اطلاعات اتصال به پراکسی (آدرس، نامکاربری، کلید). اینها ورودیهای اصلی تابع راهاندازی مرورگر هستند.
- تابع main(): با Playwright یک مرورگر Chromium را با پراکسی بالا میآورد، صفحهای باز میکند و به URL مشخص میرود. خروجی صریحی ندارد؛ هدف گرفتن صفحه و محتوای آن است (مثلاً پس از لود، میتوانید HTML را بخوانید یا دادهها را استخراج کنید).
- خطبهخط: launch(...) مرورگر را با تنظیمات پراکسی و headless اجرا میکند؛ new_page() یک تب جدید میسازد؛ goto() به صفحه میرود؛ wait_for_timeout() برای مشاهده یا منتظرماندن روی عملکرد صفحه است؛ در نهایت close() مرورگر بسته میشود.
نکته عملی: همیشه خطاهای اتصال پراکسی و تایماوتها را هندل کنید (با try/except و retry منطقی) تا اسکریپ پایدار بماند.
درک چالشهای Cloudflare
Cloudflare در نقش یک reverse proxy بین کلاینت و سرور اصلی قرار میگیرد و با ترکیبی از تکنیکهای passive و active تشخیص میدهد که آیا درخواست از یک کاربر واقعی میآید یا از یک بات. دو دستهی عمدهی چالش:
- JS Challenge: یک قطعه جاوااسکریپت به مرورگر ارسال میشود که مرورگر باید آن را اجرا کند؛ هدف، تایید اینکه جاوااسکریپت واقعی اجرا میشود.
- Interactive Challenges: نیازمند تعامل انسانی مانند کلیک یا CAPTCHA است.
تقنیات passive شامل بررسی هدرهای HTTP، اعتبار IP و fingerprinting پروتکلها (TLS/HTTP2) هستند؛ تکنیکهای active شامل canvas fingerprinting، کوئریهای خاص مرورگر و CAPTCHA میشوند. نتیجه: برای شکست این تشخیصها نیاز به ترکیب درستِ جعل fingerprint، پراکسی مناسب و تعامل شبهانسانی داریم.
Strategy 1: اسکریپ کردن مستقیم سرور (Origin IP)
اگر آدرس IP حقیقیِ سرور را داشته باشیم و میزبان بهدرستی از ناممیزبان (Host header) استفاده نکند یا سرور بهطور مستقیم پاسخ دهد، میتوان به IP رفت و از سد Cloudflare عبور کرد. این روش در عمل کمپایدار است و معمولاً زمانی جواب میدهد که میزبان نادرست کانفیگ شده باشد.
مثال (پایتون):
# دقت: ممکن است نیاز به تنظیم Host header داشته باشید
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
# مثال IP بهجا دامنه
page.goto("http://88.211.26.45/")
print(page.content())
browser.close()
هشدارها و محدودیتها:
- اگر سرور به Host header حساس باشد، باید هدر مناسب را ست کنید که خود میتواند ریسکزا باشد.
- این روش قانونی یا اخلاقی همیشه مجاز نیست؛ قبل از استفاده بررسی مالکیت و قوانین سایت لازم است.
Strategy 2: استفاده از نسخهی کششده موتورهای جستجو
گاهی میتوان به نسخهی cached که موتورهای جستجو نگه میدارند مراجعه کرد. این راه مناسب زمانی است که به محتوای ایستا نیاز دارید و نیازمند تعامل با سایت نیستید. دقت کنید که دادهٔ کششده معمولاً قدیمیتر و ناقصتر از سایت واقعی است.
نکته عملی: این روش مخصوصاً برای استخراج محتوای سئو و متنهای ایستا خوب است، اما برای دادههای داینامیک یا فرمها کاربردی نیست.
Strategy 3: شبیهسازی رفتار انسانی (Be More Human)
Cloudflare به دنبال الگوهای غیرانسانی در رفتار مرورگر است (سرعت بالای درخواستها، نبود تعامل، حرکتهای ثابت موس). افزودن نوفه و رفتار تصادفی میتواند تأثیرگذار باشد، اما نیازمند برنامهنویسی دقیق و مدیریت پیچیده است.
# نمونهای از رفتار شبهانسان: اسکرول و کلیک تصادفی (همزمانی ساده)
import random
from playwright.sync_api import sync_playwright
def human_like_navigation(page):
# چند اسکرول تصادفی
for _ in range(5):
dy = random.randint(100, 1000)
page.mouse.wheel(0, dy)
page.wait_for_timeout(random.randint(500, 3000))
page.mouse.wheel(0, -random.randint(10, 500))
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto('https://www.petsathome.com/')
page.wait_for_load_state('networkidle')
human_like_navigation(page)
browser.close()
مزایا و معایب:
- مزیت: ممکن است از برخی قوانین ساده تشخیص عبور کند.
- عیب: پیچیدگی نگهداری بالا، قابل پیشبینی شدن در مقیاس و بازده کم نسبت به هزینه توسعه.
Strategy 4: تقویت Playwright با User-Agent و پراکسی
ترکیب تنظیمات context (مثل userAgent) با پراکسیِ residential یا mobile یکی از متداولترین روشهاست. پراکسی residential آدرسهای IP واقعی کاربر را شبیهسازی میکند و با چرخشِ IP از بن و ریت لیمیت جلوگیری میکند. دقت کنید هزینه و مصرف پهنایباند را مدیریت کنید.
from playwright.sync_api import sync_playwright
RANDOM_UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ..."
PROXY = {"server": "http://residential-proxy.scrapeops.io:8181", "username": "scrapeops", "password": "KEY"}
with sync_playwright() as p:
browser = p.chromium.launch(proxy=PROXY, headless=True)
context = browser.new_context(user_agent=RANDOM_UA)
page = context.new_page()
page.goto('https://whatismybrowser.com')
print(page.content()[:500])
browser.close()
توضیحات عملی:
- از new_context(user_agent=...) برای جعل UA استفاده کنید تا fingerprint کلی مرورگر تغییر کند.
- پراکسی باید قابل اطمینان باشد؛ پراکسیهای ارزان معمولاً سریع بلاک میشوند.
- هنگام استفاده از پراکسی، زمانبندی (timeouts) را افزایش دهید چون مسیر شبکه طولانیتر میشود.
Strategy 5: استفاده از پلاگینهای Stealth (ملاحظات برای Python و Node.js)
برای Puppeteer پلاگینهایی مثل Puppeteer Extra Stealth وجود دارد که چندین پراپرتی فنگرپرینت را تغییر میدهند. برای Playwright در اکوسیستم Node.js میتوان از بستههایی که مشابه عمل میکنند استفاده کرد یا از پروژه playright-extra بهره برد. در پایتون، هنوز مجموعهای یکپارچه به اندازهی ecosystem Node وجود ندارد، اما میتوان با تزریق اسکریپتهای جاوااسکریپت و اصلاح هدرها بخش زیادی از شناساییها را خنثی کرد.
مثال مختصر جاوااسکریپت (Node.js) با playwright-extra:
const { chromium } = require('playwright-extra')
const stealth = require('puppeteer-extra-plugin-stealth')()
chromium.use(stealth)
;(async () => {
const browser = await chromium.launch({ headless: true })
const page = await browser.newPage()
await page.goto('https://whatismybrowser.com')
await page.waitForTimeout(2000)
await browser.close()
})()
توضیحات:
- در Node.js میتوان پلاگین stealth را مستقیم اضافه کرد؛ اما در پایتون باید ترکیبی از تغییر هدر، اجرای JS برای اصلاح window.navigator و استفاده از context options انجام شود.
- استفاده از stealth راهحل قطعی نیست ولی اکثر fingerprintهای ساده را کاهش میدهد.
Strategy 6: استفاده از پراکسیهای هوشمند مثل ScrapeOps
پراکسیهای هوشمند مزایایی مانند چرخش خودکار IP، کش داخلی و bypassهای سطحبندیشده برای تنظیمات امنیتی Cloudflare ارائه میدهند. مزیت اصلی این است که شما نیازی به مهندسی دقیق همهی سناریوها ندارید؛ پراکسی خودش لایههای پیچیده را مدیریت میکند.
الگوی ترافیک با پراکسی بهصورت زیر است:
- کلاینت → پراکسی
- پراکسی → سایت محافظتشده
- پراکسی نتیجه را بازمیگرداند
- کلاینت داده را پردازش میکند و در صورت نیاز درخواست بعدی ارسال میکند
نکته عملی: اگر از پراکسی استفاده میکنید، معمولاً کافیست URL را به شکل proxied یا از تنظیمات launch/proxy استفاده کنید و بقیهی منطق اسکریپ عینی شما باقی میماند. همچنین پراکسیها میتوانند مصرف API شما را بهینه کنند اما هزینه و نرخ مصرف را کنترل کنید.
مطالعهٔ موردی: مقایسهی ساده بدون پراکسی و با پراکسی
سناریو: ابتدا اسکریپی را بدون هیچگونه ترفندی اجرا میکنیم و با Cloudflare مواجه میشویم (صفحهی challenge یا CAPTCHA). سپس همان اسکریپ را با پراکسی residential اجرا میکنیم و مشاهده میکنیم که یا challenge پایینتر میآید یا اصلاً نمایش داده نمیشود.
نتیجهٔ عملی: برای بسیاری از سایتها، ترکیب پراکسیِ residential + جعل user-agent + تاخیرهای تصادفی سریعترین و کمهزینهترین راه است. روشهای پیچیدهتر (شبیهسازی کامل انسان یا پلاگینهای stealth) وقتی ضروریاند که سایت از الگوهای پیشرفتهتری بهره ببرد.
نکات امنیتی، اخلاقی و بهترینروشها
- همیشه قوانین سایت، فایل robots.txt و شرایط استفاده را بررسی کنید و اطمینان حاصل کنید که اسکریپینگ شما قانونی و اخلاقی است.
- از نرخ درخواست منطقی استفاده کنید و از backoff و retry با افزایش فاصله زمانی بهره ببرید.
- اطلاعات حساس (API keys، credential) را در متغیرهای محیطی نگه دارید و هرگز در کد سختکد نکنید.
- لاگگیری معقول و مانیتورینگ باعث میشود خطاها و بلوک شدن زود تشخیص داده شوند.
- در صورت نیاز به مقیاسبندی، از صفها، توزیع بار و پراکسیهای معتبر استفاده کنید تا از بن شدن سریع جلوگیری شود.
جمعبندی
عبور از محافظت Cloudflare معمولاً به یک ترکیب از تکنیکها نیاز دارد: پراکسی مناسب (ترجیحاً residential)، تنظیم صحیح context مرورگر (user-agent و headerها)، افزودن اتصالات شبهانسانی در صورت نیاز، و در موارد پیشرفته استفاده از stealth یا پراکسی هوشمند. برای توسعهدهندههای پایتون توصیه میشود ابتدا با یک پراکسی خوب و تنظیم user-agent شروع کنید و سپس بسته به رفتار سایت، روشهای پیچیدهتر را اضافه کنید.
اگر دنبال یک راه سریع و کمپیچیدگی هستید: استفاده از پراکسی هوشمند + تنظیم context (user-agent) معمولاً بهترین نسبت هزینه/فایده را دارد. در همه حال، مراقب قوانین و اخلاق اسکریپینگ باشید.





