مقدمه
در وب اسکریپینگ، تعامل با فرمها یکی از رایجترین و در عین حال چالشبرانگیزترین وظایف است. فرمها برای ورود داده، جستجو، بارگذاری فایل و آغاز جریانهای مختلف کاربرد دارند. در این مقاله عملی برای توسعهدهندههای پایتون سطح متوسط، تمام مراحل لازم برای پیدا کردن عناصر فرم، پر کردن آنها، ارسال اطلاعات و رفع خطاهای متداول با استفاده از Selenium پوشش داده میشود. پایان مقاله شما باید بتوانید: انتخاب درست لوکاتورها، استفاده از روشهای مختلف ارسال فرم، آپلود فایل، حل کپچا (در صورت نیاز) و راهحلهای عیبیابی را پیادهسازی کنید.
خلاصه سریع (TLDR)
پیدا کردن فرم: با driver.find_element یا driver.find_elements فرم و فیلدها را پیدا کنید.
پر کردن فیلدها: از send_keys برای وارد کردن متن و از click برای چکباکسها/رادیوها استفاده کنید.
ارسال فرم: با کلیک روی دکمه ارسال، صدا زدن submit()، ارسال Keys.ENTER یا اجرای جاوااسکریپت میتوان فرم را ارسال کرد.
انتظار و پایداری: از wait های مناسب (ضمنی/صریح) و راهبردهای fallback برای افزایش پایداری استفاده کنید.
پیدا کردن و تعامل با عناصر فرم
دو متد اصلی برای یافتن عناصر وجود دارد: find_element (یک عنصر) و find_elements (لیستی از عناصر). انتخاب دقیق لوکاتور (ID, NAME, CLASS_NAME, XPATH, CSS_SELECTOR) بهترین راه برای پایدار بودن اسکریپر است.
مثال پایهای برای باز کردن مرورگر و پر کردن فرم ورود (نمونه):
from selenium import webdriver
from selenium.webdriver.common.by import By
# launch browser
driver = webdriver.Chrome()
# navigate to a sample login page
driver.get("https://quotes.toscrape.com/login")
# find inputs
username = driver.find_element(By.ID, "username")
password = driver.find_element(By.ID, "password")
# fill inputs
username.send_keys("my_username")
password.send_keys("my-super-secret-password")
# click submit
login_btn = driver.find_element(By.XPATH, "/html/body/div/form/input[2]")
login_btn.click()
# close
driver.quit()توضیح نقش توابع و خروجیها:
webdriver.Chrome(): شی WebDriver را میسازد و یک جلسه مرورگر را باز میکند. ورودی: تنظیمات درایور (در مثال ساده none). خروجی: شی driver.
driver.get(url): صفحه را بارگذاری میکند، خروجی ندارد ولی باعث تغییر وضعیت DOM میشود.
driver.find_element(By., ...): یک عنصر وب را برمیگرداند (WebElement). اگر پیدا نشد استثناء بالا میآورد.
element.send_keys(value): متن را وارد میکند. ورودی: رشته، خروجی: None ولی مقدار فیلد تغییر میکند.
کار با چند عنصر و لیستها
برای پر کردن چند فیلد مشابه یا اعمال یک عمل روی مجموعهای از فیلدها از find_elements استفاده کنید. این روش مخصوصاً زمانی مفید است که name/id ثابت نداشته باشند ولی کلاس یا الگوی مشخصی داشته باشند.
elements = driver.find_elements(By.CLASS_NAME, "form-control")
for el in elements:
el.send_keys("sample text")نکته: ترتیب عناصر در لیست ممکن است مطابق DOM باشد؛ همیشه مطمئن شوید که عنصری که میخواهید هدف قرار دهید واقعاً عنصر مناسب است (مثلاً با بررسی element.get_attribute('name') یا element.tag_name).
پاک کردن مقادیر در ورودیها
برای حذف مقدار از فیلدها از clear() استفاده کنید. معمولاً قبل از send_keys یا برای بازنشانی فرم به کار میرود.
username = driver.find_element(By.ID, "username")
username.send_keys("temp")
# view
from time import sleep
sleep(1)
# clear
username.clear()
sleep(1)توجه: در فیلدهای پیچیده (مثل فیلدهایی که با جاوااسکریپت کنترل میشوند) ممکن است clear() کافی نباشد و نیاز به اجرای JS برای ریست مقدار باشد.
چکباکسها و رادیوها
برای انتخاب یا عدم انتخاب از click() استفاده کنید. قبل از کلیک، با is_selected() وضعیت را بررسی کنید تا از کلیکهای غیرضروری جلوگیری شود.
elements = driver.find_elements(By.CLASS_NAME, "usa-checkbox__label")
for el in elements:
if not el.is_selected():
el.click()برای رادیوها مشابه است اما معمولاً تنها یکی باید انتخاب شود. اگر المان قابل کلیک نبود، از try/except یا اجرای JS استفاده کنید.
دراپداونها (Select)
چندین روش وجود دارد: کلیک روی لیست، سپس کلیک روی گزینه؛ یا استفاده از کتابخانه selenium.webdriver.support.select.Select برای تگهای <select>.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
sel = Select(driver.find_element(By.ID, "appointment-time"))
# انتخاب با مقدار یا ایندکس
sel.select_by_value("option_value")
# یا
sel.select_by_index(2)اگر UI، یک کامپوننت جاوااسکریپتی غیرمعمول است (نه تگ select)، معمولاً باید روی لیست کلیک کرده و سپس گزینه را کلیک کنید.
روشهای ارسال فرم
بسته به سایت، چند روش برای ارسال فرم وجود دارد. همیشه سعی کنید روشی را انتخاب کنید که شبیه عملکرد انسانی باشد تا احتمال شناسایی به عنوان ربات کاهش یابد.
روش ۱ — کلیک روی دکمه ارسال
مناسب وقتی که دکمه واضح و قابل کلیک وجود دارد:
submit_button = driver.find_element(By.ID, "submit_button_id")
submit_button.click()روش ۲ — استفاده از submit()
میتوانید submit() را روی هر عنصر داخل فرم فراخوانی کنید تا فرم والد ارسال شود. مناسب زمانی که میخواهید رفتار «پیشفرض» فرم را شبیهسازی کنید.
element_in_form = driver.find_element(By.NAME, "some_form_element")
element_in_form.submit()روش ۳ — ارسال کلید Enter
اگر کاربر معمولاً با فشردن Enter فرم را ارسال میکند، میتوانید از Keys.ENTER استفاده کنید:
from selenium.webdriver.common.keys import Keys
input_field = driver.find_element(By.ID, "input_field_id")
input_field.send_keys(Keys.ENTER)روش ۴ — اجرای JavaScript
اگر تمام روشهای بالا شکست خورد، اجرای JS میتواند رویدادی را که فرم به آن گوش میدهد شبیهسازی کند (مثلاً event listeners سفارشی). اما این روش باید آخرین راه باشد چرا که مستقیماً DOM را دستکاری میکند و گاهی رفتار واقعی کاربر را عینا شبیهسازی نمیکند.
driver.execute_script("document.querySelector('.btn').click();")آپلود فایل در فرم
برای آپلود فایل به المان ورودی نوع file، کافی است مسیر مطلق فایل را از طریق send_keys ارسال کنید. استفاده از os.path.abspath تضمینکننده سازگاری بین سیستمعاملها است.
import os
file_upload = driver.find_element(By.ID, "file-input-single")
file_upload.send_keys(os.path.abspath("./example_file.txt"))نکات عملی: مجوز فایل، اندازه و محدودیتهای سرور را در نظر بگیرید؛ برای چک کردن آپلود موفق، معمولاً باید از وجود پیام موفقیت یا تغییر در DOM استفاده کنید.
کپچاها و راهحلها
کپچاها مکانیزم ضد رباتی قوی هستند. دو گزینه دارید: حل دستی (کاربر) یا استفاده از سرویسهای حل کپچا مثل 2captcha. اگر از سرویس استفاده میکنید، API key را در متغیر محیطی ذخیره کنید و هرگز آن را مستقیم در کد هاردکُد نکنید.
pip install 2captcha-pythonfrom twocaptcha import TwoCaptcha
solver = TwoCaptcha(API_KEY)
response = solver.recaptcha(sitekey=site_key, url=website)
code = response["code"]
# وارد کردن پاسخ در صفحه
response_elem = driver.find_element(By.ID, "g-recaptcha-response")
driver.execute_script(f'arguments[0].value="{code}";', response_elem)
submit = driver.find_element(By.CSS_SELECTOR, 'button[type="submit"]')
submit.click()هشدار امنیتی و قانونی: استفاده از سرویسهای حل کپچا ممکن است با سیاستهای سایت یا قوانین محلی در تضاد باشد — قبل از استفاده جوانب حقوقی را بررسی کنید.
انتظارها و پایداری — implicit vs explicit waits
سادهترین علت خطاها، تلاش برای تعامل قبل از بارگذاری کامل المانها است. دو استراتژی رایج:
Implicit wait: با driver.implicitly_wait(seconds) مقدار پیشفرضی تنظیم میکنید که هر بار Selenium منتظر پیدا شدن عنصر بماند.
Explicit wait: با WebDriverWait و expected_conditions تا زمانی که شرط خاصی (مثل حضور یا کلیکپذیری عنصر) برآورده شود صبر میکنیم.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# explicit wait example
modal = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "hs-eu-confirmation-button"))
)
modal.click()بهتر است برای قسمتهایی که محتوای پویا دارند از explicit waits استفاده کنید تا رفتار دقیقتری داشته باشید.
عیبیابی متداول و راهحلها
در زیر مسائل متداول و الگوهای حل آنها آمده است:
Element Not Found: بررسی کنید locator صحیح است، از ابزار توسعهدهنده مرورگر برای بررسی DOM استفاده کنید و از waits مناسب بهره ببرید.
Element Not Interactable: ممکن است عنصر داخل modal یا پشت لایه دیگری باشد؛ استفاده از ActionChains برای hover یا اسکرول و سپس کلیک کمک میکند. مثال:
from selenium.webdriver.common.action_chains import ActionChains
action = ActionChains(driver)
# فرض کنیم target پیدا شده است
action.move_to_element(target).click().perform()Incorrect Interaction: اگر click() یا send_keys() کار نکرد، اجرای JS یا استفاده از alternative locators معمولاً مشکل را حل میکند: driver.execute_script("arguments[0].click()", element).
Form Not Submitting: ابتدا مطمئن شوید فیلدها واقعاً پر شدهاند (inspect یا گرفتن value از طریق JS). سپس روشهای دیگر ارسال را امتحان کنید (submit(), Keys.ENTER, execute_script).
Alerts/Pop-ups: برخی modalها native نیستند و باید با locator های اختصاصی آنها را پیدا و دکمه را کلیک کنید. متدهای builtin alert.accept/dismiss فقط برای alerts واقعی مرورگر کاربرد دارند.
Iframe Handling: برای تعامل با iframe اول آن را پیدا و driver.switch_to.frame(iframe) را فراخوانی کنید؛ برای بازگشت از آن از driver.switch_to.default_content() استفاده کنید.
Browser Compatibility: همیشه درایور مرورگر (Chromedriver/Geckodriver) را با نسخه مرورگر هماهنگ نگه دارید و در صورت نیاز تست را روی چند مرورگر اجرا کنید.
بهترین روشها (Best Practices)
از متغیرهای محیطی برای نگهداری credential و API key استفاده کنید.
از explicit waits بیشتر از implicit استفاده کنید تا کنترل دقیقتری روی شرایط داشته باشید.
رفتار انسانی را شبیهسازی کنید: تأخیرهای تصادفی کوچک، حرکت ماوس و به هم نریختن الگوها (در صورت نیاز).
قوانین سایت را بررسی و به حقوق مالکیت و شرایط استفاده احترام بگذارید (robots.txt و قوانین محلی).
برای مقیاسپذیری از retry و backoff برای خطاهای شبکه یا خطاهای غیرقطعی استفاده کنید.
جمعبندی
فرمها در پروژههای وب اسکریپینگ چالشهای زیادی دارند اما با شناخت دقیق ابزارها و روشها میتوان آنها را با پایداری بالا خودکار کرد. نکات کلیدی: انتخاب لوکاتور مناسب، استفاده از waits، امتحان چند روش ارسال، محافظت از اطلاعات حساس و رعایت قوانین سایتها. با پیادهسازی الگوهایی که اینجا توضیح داده شد، میتوانید اسکریپرهای قابلاعتمادتر و مقاومتری بسازید.
آسان اسکریپ را در گوگل بهعنوان منبع ترجیحی انتخاب کن
مقالههای جدید ما زودتر و پررنگتر در نتایج گوگل و Discover برایت نمایش داده میشود. افزودن از تنظیمات گوگل





