Python: Selenium

Теория: Локаторы

Использование find_element(By.ID, By.CSS_SELECTOR, By.XPATH)

Когда браузер открывает страницу, Selenium видит её как дерево HTML-элементов — теги, атрибуты, текст. Чтобы нажать кнопку или ввести текст в поле, нужно указать, какой элемент брать. Делается это через локаторы.

Главная команда для поиска — find_element. Она принимает два аргумента: способ поиска и значение. Например, по id, по CSS-селектору или по XPath.

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


driver = webdriver.Chrome()
driver.get("https://example.com")

## Поиск по ID
login_button = driver.find_element(By.ID, "login-button")
login_button.click()

## Поиск по классу
username_input = driver.find_element(By.CLASS_NAME, "input-login")
username_input.send_keys("guest")

## Поиск по имени тега
first_link = driver.find_element(By.TAG_NAME, "a")
print(first_link.text)

## Поиск по CSS-селектору
submit_button = driver.find_element(By.CSS_SELECTOR, "form#auth button.submit")
submit_button.click()

## Поиск по XPath
logout_button = driver.find_element(By.XPATH, '//button[text()="Выйти"]')
logout_button.click()

Если нужно получить не один элемент, а все подходящие — используют find_elements.

links = driver.find_elements(By.TAG_NAME, "a")
for link in links:
    print(link.text)

Поиск внутри других элементов

Иногда на странице несколько одинаковых блоков — карточки товара, строки таблицы, статьи. Если искать элемент напрямую, Selenium может вернуть не тот, что нужен. Чтобы ограничить область поиска, можно сначала найти родительский элемент, а потом искать внутри него.

cards = driver.find_elements(By.CLASS_NAME, "product-card")

## Берём первую карточку
first_card = cards[0]

## Ищем внутри неё название и цену
title = first_card.find_element(By.CLASS_NAME, "title")
price = first_card.find_element(By.CLASS_NAME, "price")

print(title.text, price.text)

Это удобно, когда на странице десятки одинаковых элементов. Мы выбираем нужный блок и работаем только с ним.

Надёжные локаторы: принципы и примеры

Надёжный локатор — это тот, который не ломается при мелких изменениях верстки. Лучше всего использовать уникальные атрибуты: id, name или специальные data-testid, добавленные разработчиками для автотестов.

driver.find_element(By.ID, "search-input")
driver.find_element(By.CSS_SELECTOR, '[data-testid="auth-button"]')

Если таких атрибутов нет, можно использовать часть структуры, но без избыточной вложенности.

driver.find_element(By.CSS_SELECTOR, "header .nav .login a")

Ещё вариант — искать по тексту, особенно для кнопок.

driver.find_element(By.XPATH, '//button[contains(text(), "Отправить")]')

XPath мощный, но громоздкий. Если страница меняется часто — лучше CSS. Если важно найти элемент по тексту или по отношению к другому — тогда XPath.

Хорошо, когда локатор читается как фраза: “возьми кнопку с data-testid=save”. Плохо, когда он выглядит как карта метро.

Проблемы плохих локаторов

Плохие локаторы — это те, что зависят от структуры или порядка элементов. Например:

driver.find_element(By.XPATH, "//div[3]/button[1]")

Если вёрстку поменяют, тест упадёт. Также плохо, когда используется неуникальный класс:

driver.find_element(By.CLASS_NAME, "btn")

На странице может быть десятки .btn. Selenium возьмёт первую попавшуюся, и тест поведёт себя непредсказуемо.

Хуже всего — локаторы, завязанные на стили или случайные классы, которые генерирует фреймворк:

driver.find_element(By.CSS_SELECTOR, ".css-1a2b3c4")

Такие селекторы меняются при каждой сборке. Автотесты с ними не живут дольше пары релизов.

Чтобы локаторы были стабильными, нужно договориться с разработчиками о data-* атрибутах и использовать их в тестах. Например:

driver.find_element(By.CSS_SELECTOR, '[data-testid="profile-link"]')

Такой локатор не зависит от дизайна и останется рабочим даже после изменений интерфейса.

Рекомендуемые программы

+7 800 100 22 47

бесплатно по РФ

+7 495 085 21 62

бесплатно по Москве

108813 г. Москва, вн.тер.г. поселение Московский,
г. Московский, ул. Солнечная, д. 3А, стр. 1, помещ. 20Б/3
ОГРН 1217300010476
ИНН 7325174845