Автоматизация тестирования веб-приложений с помощью Selenium и Python
Основы работы с Selenium WebDriver в Python
Selenium WebDriver позволяет автоматизировать действия браузера для тестирования веб-приложений. Для начала необходимо установить библиотеку selenium и соответствующий драйвер (например, ChromeDriver).
Базовый скрипт: открытие страницы и взаимодействие с элементом
from selenium import webdriver
from selenium.webdriver.common.by import By
# Инициализация драйвера
driver = webdriver.Chrome()
driver.get('https://example.com')
# Поиск элемента по идентификатору и ввод текста
input_field = driver.find_element(By.ID, 'search')
input_field.send_keys('Selenium')
# Нажатие кнопки
button = driver.find_element(By.CLASS_NAME, 'submit-btn')
button.click()
# Закрытие браузера
driver.quit()Python selenium (selenium в python)
Пояснения: find_element возвращает первый найденный элемент, send_keys имитирует ввод текста, click нажимает кнопку. После завершения работы драйвер необходимо закрыть через quit(), чтобы освободить ресурсы.
Типичные проблемы:
- Ошибка NoSuchElementException - элемент не найден. Решение: проверить локатор, использовать ожидания (см. вариант 2).
- Ошибка WebDriverException - проблема с драйвером. Убедитесь, что версия драйвера соответствует версии браузера.
Варианты решений для типовых задач
Как найти элемент по разным локаторам?
Используйте класс By с различными стратегиями:
from selenium.webdriver.common.by import By
# По ID
elem = driver.find_element(By.ID, 'myId')
# По имени
elem = driver.find_element(By.NAME, 'username')
# По классу
elem = driver.find_element(By.CLASS_NAME, 'container')
# По css-селектору
elem = driver.find_element(By.CSS_SELECTOR, 'div.container > a')
# По xpath (точный или относительный)
elem = driver.find_element(By.XPATH, '//input[@type="submit"]')Каждый локатор подходит для разных ситуаций. Xpath наиболее гибкий, но медленнее CSS.
Распространённая ошибка:
Неправильный синтаксис CSS или XPath. Проверьте локатор через консоль браузера (например, $$('.container') для CSS).Как дождаться появления элемента на странице?
Используйте явные ожидания через WebDriverWait и expected_conditions:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10) # ждать до 10 секунд
button = wait.until(EC.element_to_be_clickable((By.ID, 'submit')))
button.click()Явные ожидания позволяют дождаться конкретного состояния элемента (видим, кликабелен, присутствует).
Проблема:
TimeoutException - элемент не появился за отведённое время. Увеличьте таймаут или проверьте правильность локатора. Также может помочь добавление неявного ожидания (implicitly_wait) для всех поисков.Как работать с выпадающим списком (select)?
Используйте класс Select:
from selenium.webdriver.support.ui import Select
select_element = driver.find_element(By.ID, 'country')
select = Select(select_element)
select.select_by_visible_text('Россия') # выбор по видимому тексту
select.select_by_value('ru') # по значению атрибута value
select.select_by_index(2) # по индексуЭто удобно для обычных HTML-списков. Если элемент не является
Ошибка:
UnexpectedTagNameException - элемент неКак обработать всплывающее окно alert?
Переключитесь на alert, примите или отклоните:
alert = driver.switch_to.alert
alert.accept() # нажать ОК
alert.dismiss() # отмена
text = alert.text # прочитать текстМетод switch_to.alert возвращает объект Alert. После обработки управление возвращается на страницу.
Ошибка:
NoAlertPresentException - alert не появился. Используйте явное ожидание EC.alert_is_present().Как выполнить JavaScript в браузере?
Метод execute_script позволяет исполнять любой JS-код:
# Скролл страницы
driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')
# Получение значения через JS
value = driver.execute_script('return document.title;')
print(value)
# Изменение атрибута элемента
elem = driver.find_element(By.ID, 'block')
driver.execute_script('arguments[0].style.display = "none";', elem)JS-инъекции полезны для скролла, манипуляции DOM и обхода ограничений тестирования.
Проблема:
Не все действия можно эмулировать через JS (например, наведение мыши). Используйте ActionChains для сложных взаимодействий.Как сделать скриншот окна?
Метод save_screenshot сохраняет изображение текущего окна:
driver.save_screenshot('screenshot.png')Для скриншота конкретного элемента используйте elem.screenshot('element.png').
Ошибка:
Размер скриншота может быть ограничен viewport. Для полной страницы понадобится скролл и склейка (библиотека Selenium-Screenshot).Как работать с iframe?
Переключитесь в iframe по индексу, имени или элементу:
# По индексу
driver.switch_to.frame(0)
# По имени или ID
driver.switch_to.frame('contentFrame')
# По веб-элементу
iframe = driver.find_element(By.TAG_NAME, 'iframe')
driver.switch_to.frame(iframe)
# После работы внутри iframe вернуться в основной документ
driver.switch_to.default_content()Все последующие поиски будут выполняться внутри выбранного iframe.
Ошибка:
NoSuchFrameException - iframe не существует. Проверьте правильность индекса или локатора. Не забудьте вернуться в default_content, если нужно работать с другими фреймами.Продвинутые примеры использования Selenium
Пример 1: Автоматизация многостраничной формы
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/form')
# Страница 1: заполнение полей
driver.find_element(By.NAME, 'firstName').send_keys('Иван')
driver.find_element(By.NAME, 'email').send_keys('ivan@mail.com')
driver.find_element(By.CLASS_NAME, 'next-btn').click()
# Страница 2: ожидание загрузки и выбор опции
wait = WebDriverWait(driver, 10)
option = wait.until(EC.element_to_be_clickable((By.XPATH, '//input[@value="option2"]')))
option.click()
submit = driver.find_element(By.ID, 'submit')
submit.click()
# Проверка успешного завершения
success_msg = WebDriverWait(driver, 5).until(
EC.presence_of_element_located((By.CLASS_NAME, 'success'))
)
print('Форма отправлена:', success_msg.text)
driver.quit()Пояснение: Используются явные ожидания для каждого шага, чтобы избежать ошибок при переходах между страницами.
Форма отправлена: Спасибо за регистрацию!
Пример 2: Извлечение данных из таблицы в pandas DataFrame
import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get('https://quotes.toscrape.com/table')
# Находим таблицу
table = driver.find_element(By.TAG_NAME, 'table')
rows = table.find_elements(By.TAG_NAME, 'tr')
data = []
for row in rows:
cols = row.find_elements(By.TAG_NAME, 'td')
if cols:
data.append([col.text for col in cols])
df = pd.DataFrame(data)
print(df.head())
driver.quit()Пояснение: Собираем все строки таблицы, извлекаем текст из ячеек. Результат конвертируется в DataFrame.
0 1 2 0 Имя Возраст Город 1 Анна 25 Москва 2 Борис 30 СПб
Пример 3: Работа с несколькими вкладками
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get('https://example.com')
# Открываем новую вкладку через JS
driver.execute_script('window.open("_blank");')
# Переключаемся на последнюю вкладку
driver.switch_to.window(driver.window_handles[-1])
driver.get('https://google.com')
print('Текущая вкладка:', driver.title)
# Вернуться на первую вкладку
driver.switch_to.window(driver.window_handles[0])
print('Первая вкладка:', driver.title)
driver.quit()Пояснение: window_handles - список всех открытых вкладок. Переключение по индексу или по дескриптору.
Текущая вкладка: Google Первая вкладка: Example Domain
Пример 4: Сохранение и использование кук для сессии
import pickle
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://example.com/login')
# Выполняем вход (заполняем логин/пароль и жмём кнопку) ...
# После успешного входа сохраняем куки
cookies = driver.get_cookies()
with open('cookies.pkl', 'wb') as f:
pickle.dump(cookies, f)
# В новом сеансе загружаем куки
driver2 = webdriver.Chrome()
driver2.get('https://example.com') # обязательно сначала открыть домен
with open('cookies.pkl', 'rb') as f:
loaded_cookies = pickle.load(f)
for cookie in loaded_cookies:
driver2.add_cookie(cookie)
driver2.get('https://example.com/dashboard')
# Теперь пользователь авторизован
driver2.quit()Пояснение: Куки сохраняются в файл, затем для новой сессии добавляются перед переходом на защищённую страницу.
(Нет вывода, но после загрузки кук страница дашборда открывается авторизованной)
Пример 5: Headless режим с настройками ChromeOptions
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('--window-size=1920x1080')
driver = webdriver.Chrome(options=options)
driver.get('https://example.com')
print(driver.title)
driver.save_screenshot('headless_screenshot.png')
driver.quit()Пояснение: Headless-режим запускает браузер без графического интерфейса. Полезно для серверов и CI.
Example Domain