Механизмы ожидания в Selenium
В Selenium механизм ожидания играет ключевую роль в обеспечении загрузки элементов страницы перед выполнением операций.
Поскольку на скорость загрузки веб-страницы влияют такие факторы, как сеть и производительность сервера, прямая работа с элементами, которые ещё не завершили загрузку, может привести к сбоям скрипта.
Selenium предоставляет несколько механизмов ожидания для решения этой проблемы.
1. Неявное ожидание (implicitly_wait)
1.1 Что такое неявное ожидание?
Неявное ожидание — это глобальный механизм ожидания, который ждёт определённое время при поиске элементов. Если элемент найден в течение указанного времени, Selenium сразу продолжит выполнение последующих операций; если элемент так и не найден по истечении тайм-аута, будет выброшено исключениеNoSuchElementExceptionисключение.
1.2 Как использовать неявное ожидание?
Неявное ожидание задаётся черезimplicitly_wait()метод. Этот метод нужно вызвать только один раз, и все последующие операции поиска элементов будут использовать это время ожидания.
Пример
from selenium.webdriver.chrome.service import Service as ChromeService
# Установите правильный путь к драйверу
service = ChromeService(executable_path="./chromedriver-mac-arm64/chromedriver")
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(service=service, options=options)
# Установить время неявного ожидания в 10 секунд
driver.implicitly_wait(10)
# Открыть веб-страницу
driver.get("https://example.com")
# Найти элемент
element = driver.find_element_by_id("element_id")
# Закройте браузер
driver.quit()
1.3 Плюсы и минусы неявного ожидания
Преимущества:
- Простое и удобное в использовании; задаётся один раз и применяется ко всем операциям поиска элементов.
- Подходит для большинства простых сценариев.
Недостатки:
- Глобальное ожидание может приводить к излишнему времени ожидания.
- Не может обрабатывать некоторые сложные условия ожидания, например ожидание, пока элемент станет кликабельным.
2. Явное ожидание (WebDriverWait и expected_conditions)
2.1 Что такое явное ожидание?
Явное ожидание — это более гибкий механизм ожидания, который позволяет задавать условия ожидания для конкретных операций. Явное ожидание обычно используется вместе сWebDriverWaitкласс иexpected_conditionsмодуль.
2.2 Как использовать явное ожидание?
Базовое использование явного ожидания выглядит следующим образом:
Пример
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import С помощью
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Установите правильный путь к драйверу
service = ChromeService(executable_path="./chromedriver-mac-arm64/chromedriver")
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(service=service, options=options)
# Открыть веб-страницу
driver.get("https://example.com")
# Установить явное ожидание, ждать до 10 секунд, пока не появится элемент
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "element_id"))
)
# Закройте браузер
driver.quit()
2.3 Часто используемые expected_conditions
expected_conditionsМодуль предоставляет множество предопределённых условий ожидания. Вот некоторые часто используемые из них:
presence_of_element_located: Ожидать, пока элемент появится в DOM.visibility_of_element_located: Ожидать, пока элемент появится в DOM и станет видимым.element_to_be_clickable: Ожидать, пока элемент станет кликабельным.text_to_be_present_in_element: Ожидать, пока текст элемента будет содержать указанный текст.
2.4 Плюсы и минусы явного ожидания
Преимущества:
- Высокая гибкость; можно задавать разные условия ожидания для разных операций.
- Позволяет обрабатывать сложные сценарии ожидания.
Недостатки:
- Код относительно сложен и требует больше кода.
- Условия ожидания нужно задавать отдельно для каждой операции.
3. Фиксированное ожидание (time.sleep)
3.1 Что такое фиксированное ожидание?
Фиксированное ожидание — простейший механизм ожидания. Оно приостанавливает выполнение скрипта на заданное время с помощьюtime.sleep()метода. Независимо от того, завершилась ли загрузка страницы, скрипт ждёт указанное время, прежде чем продолжить.
3.2 Как использовать фиксированное ожидание?
Пример
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
# Установите правильный путь к драйверу
service = ChromeService(executable_path="./chromedriver-mac-arm64/chromedriver")
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(service=service, options=options)
# Открыть веб-страницу
driver.get("https://example.com")
# Фиксированное ожидание на 5 секунд
time.sleep(5)
# Найти элемент
element = driver.find_element_by_id("element_id")
# Закройте браузер
driver.quit()
3.3 Плюсы и минусы фиксированного ожидания
Преимущества:
- Просто и легко использовать; подходит для простых тестовых сценариев.
Недостатки:
- Неэффективно и может приводить к излишнему времени ожидания.
- Невозможно динамически регулировать время ожидания в зависимости от условий загрузки страницы.
4. Гибкое ожидание (Fluent Wait)
Назначение:Динамически задавать условия ожидания, настраивать частоту опроса и игнорировать определённые исключения.
Метод:WebDriverWait в сочетании с polling_every и ignoring
Особенности:Более гибкое, подходит для сценариев, требующих динамической настройки времени ожидания.
Пример
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import С помощью
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException
# Установите правильный путь к драйверу
service = ChromeService(executable_path="./chromedriver-mac-arm64/chromedriver")
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(service=service, options=options)
driver.get("https://www.example.com")
# Настроить Fluent Wait
wait = WebDriverWait(driver, timeout=10, poll_frequency=1, ignored_exceptions=[NoSuchElementException])
element = wait.until(EC.presence_of_element_located((By.ID, "username")))
5. Итоги
- Неявное ожидание: подходит для простых сценариев, глобальное ожидание, но может приводить к ненужному времени ожидания.
- Явное ожидание: подходит для сложных сценариев, обладает высокой гибкостью, но код относительно сложен.
- Фиксированное ожидание: просто и удобно в использовании, но неэффективно; не рекомендуется для сложных тестовых сценариев.
- Fluent Wait:: подходит для сценариев, требующих динамической настройки времени ожидания.
В реальном автоматизированном тестировании рекомендуется выбирать подходящий механизм ожидания в зависимости от конкретных требований теста. Как правило, явное ожидание является наиболее рекомендуемым подходом, поскольку оно обеспечивает лучшую гибкость и эффективность.
6. Комплексный пример
Ниже приведён полный пример, демонстрирующий, как использовать неявное ожидание и явное ожидание:
Пример
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import С помощью
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Установите правильный путь к драйверу
service = ChromeService(executable_path="./chromedriver-mac-arm64/chromedriver")
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(service=service, options=options)
# Установить неявное ожидание
driver.implicitly_wait(5)
# Открыть веб-страницу
driver.get("https://www.example.com")
# Использовать явное ожидание для видимости элемента
username = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "username"))
)
username.send_keys("testuser")
# Использовать явное ожидание для кликабельности элемента
submit_button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "submit-btn"))
)
submit_button.click()
# Закройте браузер
driver.quit()