خانه/مقالات/اسکریپینگ با Selenium: انتخاب عناصر با CSS
استخراج داده
سلنیوم
برگشت به مقاله‌ها

اسکریپینگ با Selenium: انتخاب عناصر با CSS

اسکریپینگ با Selenium: انتخاب عناصر با CSS
این راهنمای فارسی و عملی به شما نشان می‌دهد چگونه با استفاده از CSS Selectors در Selenium عناصر صفحات را به‌طور دقیق و پایدار انتخاب کنید؛ از سلکتورهای پایه و صفتی تا انتظارهای صریح، مدیریت خطا و نکات بهینه‌سازی برای اسکریپینگ در پایتون.
آسان اسکریپ آسان اسکریپ
1405-06-04

مقدمه

در این مقاله به صورت عملی و جزئی به نحوهٔ یافتن عناصر HTML با استفاده از CSS Selectors در Selenium خواهیم پرداخت. فرض کنید یک توسعه‌دهندهٔ پایتون در سطح متوسط هستید که می‌خواهید اسکریپینگ (اسکریپینگ) پایدار و قابل نگهداری بنویسید؛ پس در پایان این مطلب شما می‌توانید انواع سلکتورها را بنویسید، استراتژی‌های انتظار را مدیریت کنید و خطاها را به صورت ایمن کنترل کنید.

آنچه یاد می‌گیرید:

  • اصول CSS Selector و انواع آن
  • یافتن یک یا چند عنصر با find_element و find_elements
  • انتظارهای صریح و ضمنی و مدیریت عناصر دینامیک
  • مثال‌های پایتون با توضیح ورودی‌ها، خروجی‌ها و گام‌به‌گام اجرا

مبانی CSS Selectors

CSS Selector‌ها روش‌های قدرتمندی برای اشاره به عناصر DOM هستند. انواع رایج عبارت‌اند از: نام تگ، آی‌دی (#id), کلاس (.class), صفت‌ها ([attr=value]), انتخابگرهای سلسله‌مراتبی (descendant / child) و انتخابگرهای هم‌تراز (sibling).

چند مثال ساده که در اسکریپ‌ها مفیدند:

  • div → بر اساس تگ
  • #main → بر اساس آی‌دی
  • .btn.primary → بر اساس کلاس‌ها
  • input[name='q'] → بر اساس صفت
  • div > p → فرزند مستقیم

یافتن یک عنصر با CSS Selector

برای گرفتن اولین عنصر مطابق از متد find_element استفاده می‌کنیم. ورودی‌ها و خروجی‌های اصلی:

  • ورودی‌ها: یک نمونهٔ درایور (مثلاً Chrome) و سلکتور رشته‌ای
  • خروجی: یک شیء WebElement یا پرتاب NoSuchElementException در صورت عدم پیدا شدن
from selenium import webdriver
from selenium.webdriver.common.by import By
# باز کردن مرورگر
driver = webdriver.Chrome()
# پیمایش
driver.get('https://quotes.toscrape.com')
# پیدا کردن هدر اولیه
h1 = driver.find_element(By.CSS_SELECTOR, 'h1')
print('H1:', h1.text)
driver.quit()

توضیح کد: ابتدا یک درایور کروم می‌سازیم، آدرس را لود می‌کنیم، By.CSS_SELECTOR تعیین می‌کند که رشتهٔ بعدی CSS است و پس از بازگرداندن اولین عنصر، متن آن را چاپ می‌کنیم.

یافتن تمام عناصر مطابق

برای گرفتن همهٔ عناصر مطابق از find_elements استفاده کنید که همیشه لیستی برمی‌گرداند (اگر هیچ عنصری نیابد، لیست خالی برمی‌گردد). این روش برای جمع‌آوری لیست‌ها مناسب است.

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get('https://quotes.toscrape.com')
# انتخاب تمام span ها با کلاس text
quotes = driver.find_elements(By.CSS_SELECTOR, "span.text")
for q in quotes:
    print('Quote:', q.text)
driver.quit()

توضیح: نتیجهٔ find_elements یک لیست از WebElement است؛ در حلقه می‌توانید هر کدام را استخراج و پردازش کنید.

انتظارها: مدیریت عناصر دینامیک

صفحات مدرن ممکن است عناصر را پس از بارگذاری اولیه اضافه یا تغییر دهند؛ استفاده از انتظارهای صریح (WebDriverWait + expected_conditions) بهترین روش برای تعامل امن است.

انتظار صریح برای حضور عنصر

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get('https://example.com')
# ورودی: driver و سلکتور، خروجی: WebElement پس از حاضر شدن در DOM
elem = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, '#menu-button'))
)
# اکنون می‌توانیم با elem تعامل کنیم
print(elem.tag_name)
driver.quit()

توضیح: presence_of_element_located فقط از حضور در DOM اطمینان می‌دهد، نه قابل کلیک بودن؛ برای کلیک کردن از element_to_be_clickable یا ترکیب با ActionChains استفاده کنید.

انتظار ضمنی

انتظار ضمنی با driver.implicitly_wait(seconds) تنظیم می‌شود و برای تمام فراخوانی‌های یافتن عنصر اعمال می‌گردد. ساده است اما کنترل کمتری نسبت به انتظار صریح ارائه می‌دهد.

مثال: کلیک امن با ActionChains

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get('https://example.com')
wait = WebDriverWait(driver, 10)
menu_btn = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#menu')))
actions = ActionChains(driver)
actions.move_to_element(menu_btn).click().perform()
# حالا صبر می‌کنیم تا منوی باز شده ظاهر شود
menu = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, '#menu-content')))
print(menu.text)
driver.quit()

گام‌ها: پیدا کردن دکمه، حرکت موس و کلیک (برای رفع مشکلات قابل تعامل نبودن)، سپس انتظار تا محتوای منو قابل مشاهده شود.

استفاده از سلکتورهای صفتی (Attribute Selectors)

صفت‌ها ابزار انعطاف‌پذیری برای انتخاب عناصر فراهم می‌کنند:

  • [attr] → وجود صفت
  • [attr='val'] → مقدار مساوی
  • [attr*='sub'] → حاوی
  • [attr^='start'] → شروع با
  • [attr$='end'] → پایان با
# مثال: انتخاب input هایی که name شامل 'user' است
inputs = driver.find_elements(By.CSS_SELECTOR, "input[name*='user']")
for i in inputs:
    print(i.get_attribute('name'))

نکته عملی: استفاده از صفت‌ها به جای کلاس‌های تولید شدهٔ دینامیک (مثلاً کلاس‌های حاوی هش) معمولاً پایدارتر است.

ترکیب سلکتورها و سلسله‌مراتب

با ترکیب سلکتورها می‌توانید بسیار دقیق‌تر هدف‌گیری کنید. مثال‌ها:

  • div input → همه inputهای داخل div (descendant)
  • form > input → فقط فرزندان مستقیم
  • label + input → input مجاور label
  • ul li ~ p → همه p های هم‌سطح بعد از li
# مثال ترکیب: input های متنی با کلاس form-control
fields = driver.find_elements(By.CSS_SELECTOR, "input[type='text'].form-control")
for f in fields:
    print(f.get_attribute('id'))

رفع اشکال و روش‌های متداول

وقتی عنصر پیدا نمی‌شود، ابتدا آن را در DevTools مرورگر با inspect بررسی کنید، سپس از ابزارهای زیر کمک بگیرید:

  • کپی CSS selector از DevTools و آزمایش در Console با document.querySelector
  • استفاده از انتظارهای صریح تا از زمان‌بندی صفحه مطمئن شوید
  • در صورت لزوم از XPath به عنوان جایگزین استفاده کنید، اما XPath اغلب کندتر و پرخطاتر است

مدیریت خطا

برای پایایی، خطاها را هندل کنید، مخصوصاً در پروژه‌های اسکریپینگ طولانی مدت:

from selenium.common.exceptions import NoSuchElementException

try:
    header = driver.find_element(By.CSS_SELECTOR, 'h6')
    print(header.text)
except NoSuchElementException:
    print('عنصر h6 یافت نشد')
finally:
    driver.quit()

در این الگو: اگر عنصر وجود نداشت مرورگر بسته می‌شود و اسکریپ به صورت کنترل‌شده خاتمه می‌یابد.

بهترین روش‌ها برای اسکریپینگ با CSS

  • سعی کنید سلکتورهای معنادار و کوتاه بنویسید؛ از مسیرهای بسیار طولانی و شکننده پرهیز کنید.
  • بین دقیق بودن و انعطاف‌پذیری تعادل برقرار کنید: یک سلکتور خیلی خاص با کوچک‌ترین تغییر صفحه می‌شکند.
  • از صفت‌ها و عناصر والد معنادار استفاده کنید تا شناخت ساختار صفحه سریع‌تر شود.
  • بهینه‌سازی عملکرد: فقط عناصر لازم را انتخاب کنید و از حلقه‌های غیرضروری و عملیات سنگین درون حلقه‌ها دوری کنید.
  • امنیت و مسئولیت‌پذیری: قوانین سایت را بررسی کنید و ریت لیمیت، پراکسی و مدیریت کوکی/هدرها را رعایت کنید تا شانس بلاک شدن کاهش یابد.

جمع‌بندی

با یادگیری اصول CSS selectors، روش‌های یافتن یک یا چند عنصر، و بکارگیری انتظارهای مناسب، می‌توانید اسکریپینگ با Selenium را قابل‌اطمینان‌تر و پایدارتر کنید. از صفت‌ها و ترکیب سلکتورها برای نوشتن انتخابگرهای منعطف استفاده کنید و همیشه خطاها و تغییرات DOM را در نظر بگیرید.

شروع کنید با چند صفحهٔ هدف و مجموعه‌ای از تست‌های کوچک تا سلکتورهای مناسب را پیدا کنید و آن‌ها را در پروژهٔ واقعی به کار ببرید.

مطالب مرتبط

مقاله‌های مرتبط