مقدمه
در این راهنمای عملی یاد میگیریم چگونه با استفاده از Selenium در پایتون صفحات وبی که با جاوااسکریپت رندر میشوند را اسکریپ کنیم. هدف این مقاله ارائهٔ نکات فنی، مثالهای قابل اجرا و بهترین روشها برای نصب، مدیریت WebDriver، انتظار برای بارگذاری، کلیک و اسکرول، گرفتن اسکرینشات و استفاده از پراکسی است. در پایان میدانید چه زمانی Selenium مناسب است و چه زمانی بهتر است از ابزارهایی مثل Pyppeteer یا Playwright استفاده کنید.
نصب Selenium و WebDriver
ابتدا کتابخانهٔ Selenium را نصب کنید:
pip install selenium
سپس باید WebDriver مخصوص مرورگری که میخواهید اتوماسیون کنید (مثلاً ChromeDriver برای Chrome) را تهیه و یا آن را به صورت خودکار با ابزارهایی مثل webdriver-manager مدیریت کنید. اگر WebDriver را دستی دانلود میکنید، فایل اجرایی را در PATH قرار دهید یا مسیر کامل آن را به درایور بدهید.
pip install webdriver-manager
مدیریت WebDriver — دستی یا خودکار
مدیریت دستی یعنی دانلود فایل WebDriver و بهروزرسانی آن هنگام آپدیت مرورگر؛ این روش ساده است اما نگهداری وقتگیر میشود. جایگزین بهتر استفاده از webdriver-manager است که WebDriver سازگار را بهصورت خودکار دانلود میکند.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
options = webdriver.ChromeOptions()
# نمونه: اجرای headless در صورت نیاز
options.add_argument("--headless=new")
# driver از طریق webdriver-manager نصب و راهاندازی میشود
driver = webdriver.Chrome(
service=ChromeService(ChromeDriverManager().install()),
options=options
)
driver.get('https://quotes.toscrape.com/')
driver.save_screenshot('screenshot.png')
driver.quit()
توضیح خطبهخط:
- وارد کردن ماژولها و ایجاد options برای تنظیمات مرورگر.
- ChromeDriverManager().install() مسیر WebDriver هماهنگ با مرورگر را برمیگرداند.
- driver.get صفحه را باز میکند؛ خروجی این تابع چیزی برنمیگرداند اما مرورگر را به آدرس میبرد.
- save_screenshot یک فایل تصویر از صفحه فعلی ذخیره میکند.
اسکریپ کردن صفحات با Selenium
برای استخراج دادهها ابتدا عنصر مورد نظر را پیدا کرده و متن یا صفتهای آن را میخوانیم. بهتر است از API جدید Selenium 4 و کلاس By استفاده شود.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
try:
driver.get('https://quotes.toscrape.com/')
# پیدا کردن اولین تگ h1 و گرفتن متن
title_el = driver.find_element(By.TAG_NAME, 'h1')
title = title_el.text
print('title:', title)
finally:
driver.quit()
ورودیها: آدرس صفحه. خروجی: متن عنصر پیدا شده (مثلاً عنوان). نکته: هنگام اسکریپ کردن پیچیدهتر از روشهای استخراج صریح (CSS/XPath) استفاده کنید.
ترکیب Selenium با BeautifulSoup
گاهی رندر جاوااسکریپت را با Selenium انجام میدهیم سپس HTML نهایی را با BeautifulSoup پارس میکنیم؛ این کار پردازش HTML و استخراج پیچیدهتر را راحتتر میکند.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
from bs4 import BeautifulSoup
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
try:
driver.get('https://quotes.toscrape.com/')
html = driver.page_source # HTML پس از رندر جاوااسکریپت
soup = BeautifulSoup(html, 'html.parser')
quote = soup.select_one('.quote .text')
print('quote:', quote.text if quote else 'not found')
finally:
driver.quit()
نکته: page_source همواره HTML فعلی صفحه را برمیگرداند، مناسب برای پارس کردن با کتابخانههای HTML.
منتظر ماندن برای بارگذاری (Waits)
بارگذاری کامل محتوا پیشنیاز استخراج صحیح است. سه رویکرد معمول:
- صبر ثابت با time.sleep (سرراست اما ناپایدار و کند)
- صبر ضمنی با driver.implicitly_wait(seconds) (برای همهٔ جستجوها اعمال میشود)
- صبر صریح با WebDriverWait و شرایط مورد انتظار (پایدارترین روش)
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
wait = WebDriverWait(driver, 10)
# صبر تا ظاهر شدن عنصر h1
wait.until(EC.visibility_of_element_located((By.TAG_NAME, 'h1')))
توضیح: WebDriverWait تلاش میکند تا زمانی که شرط مورد نظر (مثل قابل رؤیت بودن عنصر) برقرار شود، و در صورت عدم برقراری تا timeout خطا میدهد. این روش از صبر ثابت قابل اعتمادتر و سریعتر است.
کلیک کردن و تعامل با عناصر
برای کلیک ساده از element.click() استفاده کنید. در مواردی که کلیک کار نمیکند، میتوان از اجرای اسکریپت جاوااسکریپت یا کلاسهای Actions استفاده کرد.
# پیدا کردن لینک یا دکمه و کلیک
btn = driver.find_element(By.CSS_SELECTOR, '.next')
btn.click()
# یا با JS
driver.execute_script("arguments[0].click();", btn)
نکات عملی: پیش از کلیک، از WebDriverWait برای اطمینان از قابل کلیک بودن عنصر استفاده کنید؛ پس از کلیک ممکن است ناوبری رخ دهد، بنابراین منتظر لود مجدد صفحه باشید.
اسکرول کردن و بارگذاری بینهایت
برای صفحات با infinite scroll معمولاً باید به پایین صفحه اسکرول کرده، سپس منتظر بارگذاری و تکرار شویم:
# اسکرول تا پایین صفحه با JS
driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')
# سپس منتظر عناصر جدید یا استفاده از WebDriverWait
الگوریتم معمول:
- اسکرول تا پایین
- منتظر بارگذاری (صریح یا زمان ثابت)
- بررسی وجود آیتمهای جدید و تکرار
برای بهبود performance میتوانید Network/Resource را مسدود کنید یا از headless با بارگذاری منابع کمتر استفاده کنید.
گرفتن اسکرینشات
Selenium امکان گرفتن تصویر از صفحه یا یک عنصر را دارد:
# کل صفحه
driver.save_screenshot('full.png')
# یک عنصر
element = driver.find_element(By.CSS_SELECTOR, '.quote')
element.screenshot('quote.png')
# تنظیم اندازهٔ صفحه قبل از اسکرینشات
driver.set_window_size(1600, 900)
نکته: در حالت headless برخی روشها برای تغییر اندازه یا رندر متفاوت رفتار میکنند؛ قبل از گرفتن اسکرینشات، viewport را تنظیم کنید.
پراکسی و احراز هویت
استفاده از پراکسی برای اسکریپینگ معمول و ضروری است. برای Chrome میتوان پراکسی را هنگام راهاندازی به گزینهها داد:
options = webdriver.ChromeOptions()
options.add_argument('--proxy-server=http://ip:port')
# سپس درایور را با این options بسازید
برای پراکسیهای نیازمند احراز هویت، چند راه وجود دارد:
- گذراندن احراز هویت در سطح مرورگر یا استفاده از افزونهٔ کروم که header مربوطه را اضافه کند.
- استفاده از پراکسیهایی که احراز هویت IP-based دارند یا توکن در URL (در صورتی که سرویس اجازه دهد).
- استفاده از راهکارهای پروکسی خارجی (مانند سرویسهای پروکسی با پشتیبانی از auth) یا ابزارهایی مثل mitmproxy برای تزریق header.
برای کارهای پیچیدهتر مدیریت پراکسی و چرخش (rotation) را در لایهٔ مدیریت درخواستها طراحی کنید تا از بلاک شدن جلوگیری شود.
Pyppeteer و دیگر جایگزینها
صفحهٔ منبع نمونههایی از Pyppeteer (نسخهٔ پایتون Puppeteer) را هم نشان داده بود. این ابزار مبتنی بر API مشابه Puppeteer است و برای صفحات سنگین JS مناسب است. همچنین Playwright گزینهٔ مدرنتری است که همزمانی و API قویتری ارائه میدهد.
# نمونهٔ سادهٔ Pyppeteer: دریافت HTML رندر شده
import asyncio
from pyppeteer import launch
async def main():
browser = await launch()
page = await browser.newPage()
await page.goto('https://quotes.toscrape.com/')
html = await page.content()
await browser.close()
return html
html_response = asyncio.get_event_loop().run_until_complete(main())
# سپس میتوان html_response را با BeautifulSoup پارس کرد
مقایسهٔ کوتاه:
- Selenium: اکوسیستم بزرگ، مناسب برای اتوماسیون مرورگر و تستها؛ کار با درایورها و مرورگرهای مختلف.
- Pyppeteer / Puppeteer: کنترل دقیقتر صفحه و API نزدیک به Chrome DevTools، مناسب صفحات بسیار تعاملی.
- Playwright: پشتیبانی از چند موتور مرورگر، API مدرن، قابلیتهای قوی برای همزمانی و مدیریت context.
برای انتخاب: اگر نیاز به پشتیبانی مرورگرهای متنوع و استیبل دارید Selenium را انتخاب کنید؛ برای کار با صفحات SPA بسیار پیچیده یا نیاز به کنترل low-level، Playwright یا Pyppeteer ممکن است عملکرد بهتر و API بهتری ارائه دهند.
عملکرد، پایداری و بهترینروشها
- از WebDriverWait به جای sleep استفاده کنید تا پایدارتر باشید.
- هر بار که کار با مرورگر تمام میشود، driver.quit() را فراخوانی کنید تا حافظه آزاد شود.
- برای مقیاسپذیری از صف کاری (Job Queue) و pool مرورگر/پراکسی استفاده کنید؛ راهاندازی مرورگرهای متعدد هزینهبر است.
- آدرسهای User-Agent را بچرخانید و درخواستها را با نرخ (rate) مناسب ارسال کنید تا ریسک بلاک شدن کاهش یابد.
- در صورت نیاز به سرعت بالاتر، منابع غیرضروری مانند تصاویر و فونتها را مسدود کنید یا از headless با resource blocking استفاده کنید.
- برای مدیریت خطا از retry با exponential backoff استفاده کنید و لاگ کامل از خطاها نگه دارید.
- مسائل امنیتی: هرگز اطلاعات حساس (مثل نامکاربری/پسورد پراکسی) را در کد ثابت نگه ندارید؛ از متغیرهای محیطی یا vault استفاده کنید.
جمعبندی
در این مطلب روش نصب و پیکربندی Selenium، مدیریت WebDriver با webdriver-manager، استخراج دادهها، استفاده از BeautifulSoup برای پارسینگ، استراتژیهای انتظار، کلیک و اسکرول، گرفتن اسکرینشات و کار با پراکسیها را پوشش دادیم. اگر پروژهٔ شما مقیاس کوچک تا متوسط است، Selenium انتخاب مطمئنی است؛ برای صفحات بسیار تعاملی و نیاز به performance بالاتر، Playwright یا Pyppeteer را در نظر بگیرید. همیشه از waits صریح، مدیریت پراکسی و الگوهای retry برای پایداری استفاده کنید.
آسان اسکریپ را در گوگل بهعنوان منبع ترجیحی انتخاب کن
مقالههای جدید ما زودتر و پررنگتر در نتایج گوگل و Discover برایت نمایش داده میشود. افزودن از تنظیمات گوگل





