مقدمه
در این راهنما عملی یاد میگیریم که چه زمانی و چگونه از «هدلس براوزر»ها در پایتون برای وب اسکریپینگ استفاده کنیم. هدلس براوزرها به ما امکان اجرای جاوااسکریپت، شبیهسازی رفتار کاربر (اسکرول، کلیک، پر کردن فرم) و گرفتن اسکرینشات را میدهند بدون آنکه پنجرهای باز شود. پس از خواندن این مقاله شما میتوانید ابزار مناسب را انتخاب کنید، نمونههای کد را اجرا و آنها را برای کارهای واقعی مثل اسکرول بینهایت یا عبور از محافظهای ساده تنظیم کنید.
خلاصهٔ سریع: چرا هدلس براوزر؟
- اجرا و رندر کامل صفحه بههمراه جاوااسکریپت.
- امکان شبیهسازی تعاملات کاربر (اسکرول، کلیک، فرمها).
- قابلیت گرفتن اسکرینشات و بررسی بصری خروجی.
- قابلاستفاده بجای یا همراه با درخواستهای HTTP در سناریوهای پویا.
Selenium
Selenium یکی از قدیمیترین و شناختهشدهترین ابزارهاست؛ کنترل مرورگر واقعی (WebDriver) را فراهم میکند و اکوسیستم بزرگی دارد. مناسب پروژههایی که به پشتیبانی انواع مرورگر و یک راهحل همهجانبه نیاز دارند.
نصب (خلاصه):
pip install seleniumمثال ساده:
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("--headless")
driver = webdriver.Chrome(options=options)
driver.get("https://quotes.toscrape.com")
driver.save_screenshot("selenium-example.png")
driver.quit()توضیح کوتاه خط به خط:
- webdriver.ChromeOptions: تنظیمات مرورگر (مثل حالت هدلس).
- add_argument("--headless"): اجرای بدون GUI.
- webdriver.Chrome(options=...): راهاندازی WebDriver مطابق نسخه مرورگر محلی؛ نیاز به webdriver مناسب دارید.
- driver.get: بارگذاری URL.
- save_screenshot: ذخیره تصویر رندر شده.
نکات عملی و محدودیتها:
- مصرف منابع نسبتاً بالا؛ بهتر است در پروسههای محدود یا ماشینهای قوی اجرا شود.
- هماهنگی نسخه WebDriver با مرورگر ضروری است (قابلیت استفاده از webdriver-manager برای اتوماتیکسازی وجود دارد).
- برای موازیسازی مقیاسپذیری نیاز به مدیریت پروسهها و حافظه است.
Playwright
Playwright برای پشتیبانی قدرتمند از حالتهای async طراحی شده و عملکرد بسیار بهتری در همزمانی نسبت به Selenium دارد. اتو-ویت (auto-wait) و API جدید برای مدیریت contextها از مزایای آن است.
نکتهٔ معماری: Playwright چند موتور مرورگر را پشتیبانی میکند و API آن برای نوشتن اسکریپتهای async تمیز مناسب است.
نصب (خلاصه):
pip install playwright
# سپس اجرا: playwright installمثال async:
from playwright.async_api import async_playwright
import asyncio
async def run(playwright):
browser = await playwright.chromium.launch(headless=True)
page = await browser.new_page()
await page.goto("https://quotes.toscrape.com")
await page.screenshot(path="playwright-example.png", full_page=True)
await browser.close()
async def main():
async with async_playwright() as playwright:
await run(playwright)
asyncio.run(main())نکات اجرایی:
- await برای عملیات I/O و تعامل با صفحه لازم است.
- full_page=True امکان گرفتن اسکرینشات تمام صفحه را میدهد.
- Playwright برای تست و استخراج دادههای پویا و صفحات با اسکرول طولانی مناسب است.
بهینهسازی و بهترین روشها:
- برای مقیاس بالا از browser contexts استفاده کنید تا هر تسک ایزوله شود.
- استفاده از پروکسی، کوکی و هدر سفارشی برای عبور از بررسیهای سادهٔ سرور لازم است.
Pyppeteer (Puppeteer در نسخهٔ پایتون)
Pyppeteer پورت پایتون Puppeteer است و تمرکز روی کرومیوم دارد؛ سبکتر از Selenium ولی هنوز async است.
مزایا: سبک، async، سینتکس مشابه Puppeteer.
معایب: محدود به Chromium و تفاوتهایی با نسخهٔ اصلی JS دارد.
pip install pyppeteer
# سپس ممکن است بخواهید: pyppeteer-installimport asyncio
from pyppeteer import launch
async def main():
browser = await launch()
page = await browser.newPage()
await page.goto("https://quotes.toscrape.com")
await page.screenshot({'path': 'pyppeteer-example.png', 'fullPage': True})
await browser.close()
asyncio.get_event_loop().run_until_complete(main())همانند Playwright، باید با الگوی async آشنا باشید؛ تفاوت اصلی در قابلیتها و پشتیبانی مرورگر است.
Splash
Splash یک رندرر بسیار سبک است که بهصورت سروری اجرا میشود؛ دستورات را بهصورت پارامترهای HTTP دریافت میکند و خروجی را برمیگرداند. مناسب محیطهای کممنبع و زمانی که میخواهید از هر HTTP client دلخواه استفاده کنید.
راهاندازی با داکر:
sudo docker pull scrapinghub/splash
docker run -p 8050:8050 scrapinghub/splashنمونهٔ استفاده با requests:
import requests
splash_url = "http://localhost:8050/render.png"
target_url = "https://quotes.toscrape.com"
params = {"url": target_url, "wait": 2}
response = requests.get(splash_url, params=params)
with open("splash-quotes.png", "wb") as f:
f.write(response.content)نکات:
- نیاز به اجرای سرویس (مثلاً در Docker) دارد.
- بسیار سبک و مناسب برای اسکریپتهایی که میخواهند از requests استفاده کنند.
- پیکربندی و خطاگیری ممکن است پیچیدهتر باشد (لگهای Splash را بررسی کنید).
Headless عبر پروکسی (مثلاً سرویسهای third-party)
بهجای اجرای مرورگر محلی، میتوانید از سرویسهایی استفاده کنید که رندر را در سرور انجام میدهند و خروجی HTML یا تصویر را برمیگردانند. مزیتها: نیازی به مدیریت سرور یا WebDriver ندارید، معایب: هزینه، تأخیر شبکه و نیاز به کلید API.
مثال تبدیل HTML به تصویر با imgkit (پس از دریافت HTML از پروکسی):
import requests
import imgkit
proxy_url = "https://proxy.example.com/v1/"
target_url = "https://quotes.toscrape.com"
params = {"api_key": "YOUR-SUPER-SECRET-API-KEY", "url": target_url, "wait": 2}
response = requests.get(proxy_url, params=params, timeout=120)
imgkit.from_string(response.text, "proxy-quotes.png")توجه: تبدیل HTML به تصویر ممکن است استایلها (CSS) یا اسکریپتهای خارجی را بهدرستی اعمال نکند؛ برای نمای دقیقتر از رندر داخل براوزر استفاده کنید.
مقایسهٔ عملی و راهنمای انتخاب
چند معیار مهم برای انتخاب:
- پشتیبانی از async: اگر میخواهید تعداد زیادی صفحه همزمان باز کنید، Playwright یا Pyppeteer انتخابهای بهتریاند.
- پشتیبانی مرورگر: Selenium برای چند مررورگر مناسب است؛ Pyppeteer محدود به Chromium است.
- منابع: Splash و خدمات پروکسی کممصرفترند و برای مقیاس با منابع محدود مناسبترند.
- نیاز به پروکسی/ردیابی محافظها: سرویسهای پروکسی یا راهکارهایی با پشتیبانی پیشرفته پروکسی و دورزدن بنینگ مزیت دارند.
چه زمانی هر کدام را انتخاب کنید (خلاصه):
- Selenium: اگر به سازگاری مرورگر و اکوسیستم بزرگ نیاز دارید یا در پروژههای قدیمی کار میکنید.
- Playwright: اگر دنبال همزمانی، دقت بالا و قابلیت full-page screenshot هستید.
- Pyppeteer: اگر میخواهید یک گزینهٔ سبکتر مبتنی بر کرومیوم داشته باشید.
- Splash: اگر میخواهید با requests کار کنید و منابع محدود دارید.
- سرویس پروکسی/Headless-as-a-Service: اگر مدیریت زیرساخت برایتان هزینهبر است و نیاز به پروکسی داخلی دارید.
مثال کاربردی: اسکرول بینهایت (Playwright)
اسکرول بینهایت را اغلب با هدلس براوزرها حل میکنند؛ رویکرد ساده: اسکرول به انتهای صفحه، منتظر لود شدن، تکرار تا رسیدن به شرط توقف.
# helper برای اسکرول در Playwright
async def scroll_page(page, scroll_pause=0.5, max_scrolls=20):
for _ in range(max_scrolls):
await page.evaluate("window.scrollBy(0, document.body.scrollHeight)")
await page.wait_for_timeout(int(scroll_pause * 1000))ورودیها و خروجیها:
- ورودی: page (صفحه Playwright)، scroll_pause (توقف بین اسکرولها)، max_scrolls (حداکثر دفعات اسکرول).
- خروجی: هیچ مقدار برنمیگرداند؛ اما DOM صفحه بعد از هر اسکرول بهروزرسانی میشود و میتوانید با page.content() یا استخراج المنتها دادهها را بخوانید.
نکات عملی:
- همیشه شرط توقف منطقی (مثلاً بر اساس تغییر تعداد آیتمها یا بعد از چند تکرار بدون نتیجه) قرار دهید تا لوپ بینهایت نشود.
- استفاده از wait_for_selector یا بررسی تغییر در DOM قابلاطمینانتر از فقط sleep است.
بهترین روشها، امنیت و پایداری
- سرعت و نرخ درخواست: از rate limiting و backoff تصاعدی برای جلوگیری از بلاک شدن استفاده کنید.
- هدرها و User-Agent: حتما هدرهای واقعی بگذارید و در صورت امکان از لیستهای چرخشی برای User-Agent بهره ببرید.
- مدیریت نشست: برای کار با صفحات لاگینشده از کوکیها و session reuse استفاده کنید.
- خطاها و retry: در عملیات شبکه و render احتمال خطا دهید و با استراتژی retry کنترلشده آنها را هندل کنید.
- استفاده از headful برای دیباگ: هنگام توسعه از حالت غیرهدلس استفاده کنید تا DOM و کنسول را مشاهده کنید.
- مسائل حقوقی: همیشه قوانین سایت، فایل robots.txt و مقررات استفاده را رعایت کنید؛ از جمعآوری دادههای حساس پرهیز کنید.
جمعبندی
هدلس براوزرها ابزارهای قدرتمندی برای اسکریپینگ صفحات پویا هستند. انتخاب بین Selenium، Playwright، Pyppeteer، Splash یا سرویسهای پروکسی وابسته به نیازهای شما در زمینه منابع، همزمانی، پشتیبانی مرورگر و نیاز به عبور از محافظهاست. برای پروژههای مقیاسپذیر و همزمانی بالا Playwright پیشنهاد میشود؛ برای سادگی و اجرای سبکتر Splash یا سرویس پروکسی میتواند مناسب باشد. همیشه بهترینروشها (مدیریت پروکسی، کوکی، ریتری و احترام به قوانین سایت) را رعایت کنید و در محیط توسعه با حالت headful دیباگ کنید.
حالا نوبت شماست: یکی از مثالها را روی سایت هدفتان اجرا کنید، لاگها را بررسی کنید و طبق نیازتان هدر/پروکسی و مدیریت نشست اضافه کنید.





