Python Programming

ساخت اسکریپرهای مقاوم در برابر ربات‌ها با استفاده از Selenium و Headless Chrome

زمینه وب‌اسکرپینگ یک مسابقه تسلیحاتی مداوم بین استخراج‌کنندگان داده و مالکان وب‌سایت‌ها است. با پیشرفته‌تر شدن دفاع‌های ضد ربات مانند Cloudflare، DataDome و PerimeterX، کتابخانه‌های درخواست استاندارد اغلب در دور زدن مکانیسم‌های تشخیص مدرن شکست می‌خورند. برای توسعه‌دهندگان متوسط و پیشرفته پایتون، راه‌حل نه در ابزارهای ساده‌تر، بلکه در اتوماسیون مرورگر پیچیده‌تر نهفته است. این راهنما بررسی می‌کند که چگونه می‌توان اسکریپرهای مقاوم و ضد ربات را با استفاده از Selenium و Headless Chrome ساخت، با تمرکز بر تقلید از رفتار انسانی و گریز از تشخیص.

چرا Headless Chrome و Selenium؟

کلاینت‌های HTTP سنتی درخواست‌هایی ارسال می‌کنند که فاقد زمینه یک محیط مرورگر واقعی هستند. آن‌ها جاوااسکریپت را اجرا نمی‌کنند، CSS را رندر نمی‌کنند و کوکی‌ها را در طول جلسات به همان روشی که یک کاربر انسانی انجام می‌دهد، حفظ نمی‌کنند. وب‌سایت‌های مدرن به شدت به جاوااسکریپت سمت کلاینت برای بارگذاری محتوای پویا و پیاده‌سازی تکنیک‌های ردیابی (فینگرپرینتینگ) برای شناسایی اسکریپت‌های خودکار تکیه دارند.

Selenium به عنوان پلی برای کنترل یک نمونه مرورگر واقعی عمل می‌کند—به طور خاص Chrome در این زمینه. با استفاده از Headless Chrome، می‌توانیم از موتور رندر کامل یک مرورگر بدون بار اضافه رابط کاربری گرافیکی بهره ببریم. این کار دسترسی به DOM، کوکی‌ها و ذخیره‌سازی محلی را فراهم می‌کند و تشخیص تفاوت بین یک ربات و یک کاربر انسانی را برای وب‌سایت‌ها به طور قابل توجهی دشوارتر می‌سازد.

راه‌اندازی درایور با گزینه‌های مخفی‌سازی

اولین قدم در ساخت یک اسکریپر مقاوم در برابر ربات، پیکربندی صحیح گزینه‌های Chrome است. به طور پیش‌فرض، مرورگرهای بدون رابط گرافیکی (Headless) از طریق پرچم‌ها و ویژگی‌های خاصی که سیستم‌های امنیتی آن‌ها را تشخیص می‌دهند، خود را آشکار می‌کنند. ما باید این ردپاهای دیجیتال را حذف کنیم.

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

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service

def setup_driver():
    chrome_options = Options()
    
    # Run in headless mode
    chrome_options.add_argument("--headless=new")
    
    # Remove automation clues
    chrome_options.add_argument("--disable-blink-features=AutomationControlled")
    chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
    chrome_options.add_experimental_option('useAutomationExtension', False)
    
    # Essential for stability and stealth
    chrome_options.add_argument("--no-sandbox")
    chrome_options.add_argument("--disable-dev-shm-usage")
    chrome_options.add_argument("--window-size=1920,1080")
    chrome_options.add_argument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
    
    driver = webdriver.Chrome(service=Service(), options=chrome_options)
    
    # Execute CDP command to override navigator.webdriver
    driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
        "source": "Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"
    })
    
    return driver

driver = setup_driver()

حیاتی‌ترین خط در کد بالا، دستور CDP (پروتکل ابزارهای توسعه‌دهنده Chrome) است. این خط ویژگی navigator.webdriver را اصلاح می‌کند که نشانگر اصلی مورد استفاده توسط بسیاری از خدمات ضد ربات برای تشخیص اتوماسیون است. با تنظیم آن روی undefined، حضور ربات را پنهان می‌کنیم.

تقلید از رفتار انسانی

حتی اگر موفق شوید واقعیت استفاده از مرورگر را پنهان کنید، الگوهای تعامل شما ممکن است همچنان تشخیص داده شوند. ربات‌ها اغلب به سرعت حرکت می‌کنند، بدون تردید کلیک می‌کنند یا با سرعت‌های ثابت اسکرول می‌کنند. برای ظاهر شدن به عنوان یک انسان، باید تصادفی‌سازی و تأخیر را وارد کنیم.

استفاده از ActionChains در Selenium یا انتظارهای صریح ساده می‌تواند کمک کند. برای مثال، هرگز بلافاصله پس از راه‌اندازی درایور، مستقیماً به یک صفحه ناوبری نکنید. یک تأخیر تصادفی برای شبیه‌سازی زمان تفکر کاربر اضافه کنید:

import time
import random

def human_delay(min_seconds=2, max_seconds=5):
    time.sleep(random.uniform(min_seconds, max_seconds))

# Example usage
human_delay()
driver.get("https://example.com")
human_delay()

علاوه بر این، در نظر بگیرید که از چرخش کاربرپیش‌فرض‌ها (User Agents) و IPهای پروکسی استفاده کنید. اگرچه این کار به یک زیرساخت قوی نیاز دارد، اما برای عملیات اسکرپینگ در مقیاس بزرگ ضروری است. همیشه مطمئن شوید که IPهای پروکسی شما مسکونی یا موبایل هستند، نه IPهای دیتاسنتر، زیرا دومی به راحتی در لیست سیاه قرار می‌گیرند.

مدیریت محتوای پویا و بررسی‌های ضد ربات

سیستم‌های ضد ربات بسیاری قبل از اجازه دسترسی به محتوا، CAPTCHAها یا صفحات چالش را ارائه می‌دهند. Selenium به شما اجازه می‌دهد با این عناصر دقیقاً مانند یک انسان تعامل داشته باشید. با این حال، خودکارسازی حل CAPTCHA پیچیده است و اغلب برخلاف شرایط خدمات است. رویکرد بهتری پیاده‌سازی منطق تلاش مجدد قوی و کاهش نمایی (exponential backoff) است.

اگر صفحه‌ای بارگذاری نشود یا چالشی ظاهر شود، برای یک دوره تصادفی صبر کنید و دوباره تلاش کنید. این کار شبیه به کاربری است که ممکن است اتصال کندی داشته باشد یا با یک خرابی موقت مواجه شده باشد، نه یک اسکریپت که مکرراً سرور را مورد حمله قرار می‌دهد.

from selenium.common.exceptions import TimeoutException

try:
    driver.find_element_by_css_selector(".content")
except TimeoutException:
    print("Content not loaded, retrying...")
    human_delay(5, 15)
    driver.refresh()

نتیجه‌گیری

ساخت اسکریپرهای مقاوم در برابر ربات دیگر درباره نوشتن یک اسکریپت سریع با requests نیست. این کار نیازمند درک جامع از محیط‌های مرورگر، تکنیک‌های ردیابی (فینگرپرینتینگ) و الگوهای تعامل شبیه به انسان است. با استفاده از Selenium همراه با Headless Chrome پیکربندی شده با دقت، پنهان کردن سیگنال‌های اتوماسیون و وارد کردن تصادفی‌سازی رفتاری، می‌توانید نرخ موفقیت پروژه‌های اسکرپینگ خود را به طور قابل توجهی افزایش دهید. به یاد داشته باشید که فایل robots.txt و شرایط خدمات وب‌سایت‌ها را محترم بشمارید، تا اطمینان حاصل کنید که فعالیت‌های اسکرپینگ شما اخلاقی و پایدار باقی می‌مانند.

Share: