مقدمه
در این مقاله عملی یاد میگیرید چگونه با استفاده از Selenium منابع غیرضروری صفحه (مثل تصاویر، CSS، فونتها، رسانهها و درخواستهای AJAX) را در مرورگر مسدود کنید تا سرعت اسکریپینگ بالا رفته و مصرف داده کاهش یابد. مثالها در Python هستند و برای هر روش توضیح میدهیم چه چیزی ورودی است، چه خروجیای میگیرید و هر خط کد چه نقشی دارد.
راهنمای سریع (TL;DR)
ایجاد شئ گزینهها: یک webdriver.ChromeOptions یا معادل Firefox را بسازید.
تنظیم ترجیحات/دستورات CDP: برای تصاویر از prefs استفاده کنید یا با CDP URLها را بلاک کنید.
راهاندازی WebDriver: WebDriver را با گزینههای تنظیمشده بسازید و صفحه را بارگذاری کنید.
نمونه سریع بلاک تصاویر در Chrome:
from selenium import webdriver
# 1) ساخت ChromeOptions
options = webdriver.ChromeOptions()
# 2) تنظیم pref برای غیرفعال کردن تصاویر
prefs = {"profile.managed_default_content_settings.images": 2}
options.add_experimental_option("prefs", prefs)
# 3) ساخت WebDriver با گزینهها
driver = webdriver.Chrome(options=options)
# 4) ناوبری به صفحه
driver.get('https://example.com')
شرح: ورودی این مثال یک دیکشنری prefs است که به Chrome میگوید تصاویر را بارگذاری نکند. خروجی یک driver است که با آن صفحات بدون تصاویر باز میشوند. قدمها: ایجاد گزینهها → اضافه کردن prefs → ساخت WebDriver → get().
بلاک کردن تصاویر — Chrome و Firefox
ایده کلی: مرورگرها ترجیحات یا APIهای متفاوتی دارند؛ Chrome با prefs و CDP و Firefox با set_preference کار میکند.
Chrome (روش استاندارد)
from selenium import webdriver
options = webdriver.ChromeOptions()
prefs = {"profile.managed_default_content_settings.images": 2}
options.add_experimental_option("prefs", prefs)
driver = webdriver.Chrome(options=options)
driver.get('https://en.wikipedia.org/wiki/Main_Page')
توضیح خط به خط: ChromeOptions را میسازیم، کلید تنظیم تصاویر را به 2 (مسدود) قرار میدهیم، گزینه را به WebDriver میدهیم و صفحه را باز میکنیم. اگر تصاویر هنوز نمایش داده شدند، احتمالاً تنظیمات از قبل اعمال نشدهاند یا نسخه chromedriver با Chrome سازگار نیست.
Firefox
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
options = Options()
# 2 یعنی مسدود کردن تصاویر
options.set_preference("permissions.default.image", 2)
driver = webdriver.Firefox(options=options)
driver.get('https://en.wikipedia.org/wiki/Main_Page')
توضیح: در Firefox از set_preference استفاده میکنیم؛ ورودی یک کلید رشتهای است و خروجی WebDriver است. توجه کنید که رفتار prefs بین نسخهها ممکن است متفاوت باشد.
بلاک منابع با Chrome DevTools Protocol (CDP)
برای مسدودسازی CSS، فونت، رسانه و حتی اسکریپتها، CDP کنترل دقیقتری میدهد. شما با execute_cdp_cmd میتوانید URL-patternها را مسدود کنید یا JavaScript را غیرفعال کنید.
from selenium import webdriver
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(options=options)
# فعال کردن شبکه و تعیین الگوهای مسدودشده
# مثال: بلاک کردن فایلهای CSS، فونت و رسانه
driver.execute_cdp_cmd("Network.enable", {})
driver.execute_cdp_cmd("Network.setBlockedURLs", {"urls": ["*.css", "*.woff2", "*.mp4"]})
# برای غیرفعال کردن اجرای JS (با احتیاط)
driver.execute_cdp_cmd("Page.setJavaScriptEnabled", {"enabled": False})
# رفرش برای اعمال قوانین
driver.get('https://example.com')
driver.refresh()
شرح: اولین فراخوانی (Network.enable) شبکه DevTools را فعال میکند. بعد Network.setBlockedURLs الگوهای URL را میگیرد و آنها را بلاک میکند. Page.setJavaScriptEnabled اجرای JS را خاموش میکند که ممکن است باعث از دست رفتن محتوای دینامیک شود؛ در نتیجه پیش از استفاده تست کنید.
بلاک کردن XHR/Fetch و مدیریت AJAX
مسدودسازی درخواستهای AJAX و XHR چالش بیشتری دارد چون URLها ممکن است هنگام اجرا ساخته شوند. گزینههای معمول:
- استفاده از Network.setBlockedURLs برای بلاک کردن الگوهای شناختهشده (مثلاً *.json یا دامنههای خاص).
- استفاده از یک پروکسی (مثل یک proxy محلی یا ابزار MITM) برای فیلتر و تغییر ترافیک بهصورت بلادرنگ.
- تزریق اسکریپت در صفحه برای بازنویسی fetch یا XMLHttpRequest و جلوگیری از فراخوانیهای ناخواسته (روش کمدقت و پتانسیل ایجاد خطا).
مثال ساده مسدودسازی endpoint معروف با CDP:
# بلوک کردن فایلهای json و endpointهای api.example.com
driver.execute_cdp_cmd("Network.setBlockedURLs", {"urls": ["*.json", "*://api.example.com/*"]})
توضیح: این روش روی درخواستهایی که با الگو تطابق دارند کار میکند ولی اگر URLها در زمان اجرا تغییر کنند یا با کوئریهای پیچیده باشند، پروکسی راهحل قابلاطمینانتری است.
مدیریت محتوای دینامیک و همگامسازی
در صفحات تکصفحهای و AJAX-heavy باید از مکانیزمهای همگامسازی استفاده کنید تا مطمئن شوید عنصر مورد نظر بعد از اعمال قوانین بارگذاری شده است. نکات عملی:
- از WebDriverWait و شرایط صبر صریح (explicit waits) استفاده کنید.
- قوانین CDP را قبل از بارگذاری صفحه اعمال کنید (تا منابع اولیه نیز بلاک شوند).
- برای محتوای پویا، پس از وقوع رویدادهای خاص، قوانین را مجدداً اعمال یا صفحه را رفرش کنید.
اشکالزدایی، محدودیتها و امنیت
- سازگاری نسخهها: همیشه نسخه chromedriver/geckodriver را با مرورگر هماهنگ کنید؛ بسیاری از خطاها از ناسازگاری ناشی میشود.
- تغییر رفتار صفحه: غیرفعال کردن JS یا CSS ممکن است عنصرهای مورد نیاز شما را حذف کند؛ قبل از غیرفعالسازی کامل، بررسی کنید چه چیزی ضروری است.
- محدودیتها: برخی منابع ممکن است قبل از اعمال قوانین بارگذاری شوند؛ اعمال CDP پیش از فراخوانی get شانس موفقیت را افزایش میدهد.
- امنیت: اگر از پروکسی استفاده میکنید، مراقب اطلاعات حساس (کوکیها، توکنها) باشید و ترافیک را امن نگه دارید.
بهترین روشها
- برای اسکریپینگ مقیاسپذیر، از headless mode همراه با resource blocking استفاده کنید تا مصرف CPU/GPU کاهش یابد.
- قوانین بلاک را در یک تابع جداگانه بستهبندی کنید تا قابل تست و قابل بازیابی باشد.
- تنظیمات را مستندسازی کنید و در CI تست کنید (نسخهبندی WebDriver و مرورگر).
- برای جلوگیری از شناسایی و جلوگیری از بلاک شدن، به تدریج رفتارها را شبیهسازی کنید و از پروکسی/روتیشن IP استفاده نمایید.
- قبل از مسدودسازی کامل جاوااسکریپت، با غیرفعالسازی بخشبهبخش تست کنید تا محتوای مورد نیاز از دست نرود.
مطالعه موردی: Wikipedia — مقایسه ساده
نمونه پایه بدون بلاک (برای مقایسه):
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get('https://en.wikipedia.org/wiki/Main_Page')
section = driver.find_element(By.CSS_SELECTOR, 'div#mp-dyk')
print(section.text)
driver.quit()
و نسخه با بلاک منابع (تصاویر و CSS را بلاک میکنیم):
from selenium import webdriver
from selenium.webdriver.common.by import By
options = webdriver.ChromeOptions()
# بلاک تصاویر و فایلهای CSS
options.add_experimental_option('prefs', {"profile.managed_default_content_settings.images": 2})
driver = webdriver.Chrome(options=options)
driver.get('https://en.wikipedia.org/wiki/Main_Page')
section = driver.find_element(By.CSS_SELECTOR, 'div#mp-dyk')
print(section.text)
driver.quit()
نتیجه عملی: نسخه با بلاک عموماً سریعتر لود میشود و مصرف داده کمتر است، اما همیشه صحت محتوای استخراجشده را بررسی کنید تا مطمئن شوید چیزی حذف نشده است.
جمعبندی
مسدودسازی منابع در Selenium ابزار قدرتمندی برای بهینهسازی سرعت و کاهش مصرف پهنای باند در اسکریپینگ است. از روشهای ساده prefs در Chrome/Firefox برای تصاویر استفاده کنید، و برای کنترل دقیقتر از CDP یا پروکسی بهره ببرید. همیشه تأثیر مسدودسازی روی محتوای هدف را ارزیابی کنید و از waits و تستهای مداوم برای اطمینان از پایداری اسکریپتها بهره ببرید.





