📖 Теория: конспект локаторов Selenium (Урок 05)
⚡ Краткий конспект локаторов
- Локатор — способ однозначно определить элемент на странице. Используется через класс
By. - DevTools: F12 → Elements → ПКМ → Copy selector / Copy XPath.
- CSS:
#id,.class,[name="val"],parent child,parent > child,[href*="фрагмент"]. - XPath:
//*[@id="..."],//tag[text()="..."],//tag[contains(@attr,"...")],//parent/childvs//parent//child. find_element()→ WebElement илиNoSuchElementException.find_elements()→ list[WebElement] или[].is_displayed()→ True/False;.text→ только видимый текст.
Что такое локатор веб-элемента
Локатор веб-элемента — это способ однозначно определить нужный элемент на веб-странице. Он используется для взаимодействия с HTML-элементами: кнопками, полями ввода, ссылками и другими тегами.
Как найти локатор в DevTools
Для определения локатора используйте инструменты разработчика браузера.
Как открыть DevTools
- Правый клик по элементу → «Просмотреть код» (Inspect)
- Или нажать F12 / Ctrl + Shift + I (Windows) / Cmd + Option + I (Mac)
- Переключиться на вкладку Elements (Элементы)
Как быстро скопировать локатор
В панели Elements — правый клик по нужному тегу → Copy → выбрать:
- «Copy selector» — получить CSS-селектор
- «Copy XPath» — получить XPath
/html/body/div[3]/div/form/input[1]). Любое изменение HTML-структуры сломает такой локатор. Пишите XPath вручную на основе стабильных атрибутов.
CSS-селекторы
CSS-селекторы считаются быстрыми и удобными. Рекомендуются для большинства задач автоматизации.
По ID
<!-- HTML -->
<input id="username" type="text">
<!-- CSS-селектор -->
#username
По атрибуту name
<!-- HTML -->
<input name="email" type="text">
<!-- CSS-селектор -->
[name="email"]
По классу
<!-- HTML -->
<button class="btn-primary">Login</button>
<!-- CSS-селектор -->
.btn-primary
По вложенности: прямой и любой потомок
<!-- HTML -->
<div class="container">
<button>Купить</button>
</div>
<!-- CSS: любой button внутри .container (любая глубина) -->
.container button
<!-- CSS: только прямой потомок .container -->
.container > button
.card-body > p — только прямые дочерние p. .card-body p — все p на любой глубине.
По частичному совпадению атрибута
<!-- HTML -->
<a href="/products/view/123">Подробнее</a>
<!-- CSS-селектор: *= ищет подстроку в значении атрибута -->
a[href*="/products/view/"]
XPath
XPath — язык запросов для поиска элементов в иерархической HTML-структуре. Мощнее CSS: позволяет искать по тексту и перемещаться вверх по дереву DOM. Как правило, медленнее CSS-селекторов.
Основной синтаксис XPath
| Синтаксис | Смысл |
|---|---|
//*[@id="val"] | Любой элемент с id="val" |
//tag[@attr="val"] | Элемент tag с атрибутом attr="val" |
//tag[text()="..."] | Поиск по точному тексту |
//tag[contains(@attr,"...")] | Частичное совпадение атрибута |
//parent/child | Только прямой потомок (один уровень) |
//parent//child | Любой потомок (любая глубина) |
Примеры XPath (на базе suninjuly.github.io/cats.html)
<!-- По ID -->
//*[@id="bullet"]
<!-- По классу (может вернуть несколько!) -->
//*[@class="card-text"]
<!-- По атрибуту name -->
//p[@name="Vova"]
<!-- По тексту кнопки -->
//button[text()="View"]
<!-- По частичному совпадению атрибута src -->
//img[contains(@src, "serious_cat")]
<!-- Прямой потомок -->
//div[@class="btn-group"]/button
<!-- Любой потомок -->
//div[@class="card-body"]//button
Метод find_element()
Ищет первый элемент, соответствующий локатору. Возвращает объект WebElement. Если не найден — выбрасывает NoSuchElementException.
# test_locators.py
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("http://example.com")
# По ID
element = driver.find_element(By.ID, "login-button")
# По классу
element = driver.find_element(By.CLASS_NAME, "button-primary")
# По CSS-селектору
element = driver.find_element(By.CSS_SELECTOR, "div.container > p")
# По XPath
element = driver.find_element(By.XPATH, "//button[text()='Отправить']")
# По атрибуту name
element = driver.find_element(By.NAME, "username")
print(element.text) # Читаем видимый текст
driver.quit()
Обработка NoSuchElementException
# test_exception.py
from selenium.common.exceptions import NoSuchElementException
try:
element = driver.find_element(By.ID, "non-existent")
print("Элемент найден")
except NoSuchElementException:
print("Элемент не найден")
Свойство .text
Возвращает видимый текст внутри элемента. Скрытый текст (display: none, visibility: hidden) не считывается.
# test_text.py
header = driver.find_element(By.TAG_NAME, "h1")
print(header.text) # Выведет текст заголовка h1
Метод is_displayed()
Проверяет, видим ли элемент пользователю. Возвращает True или False.
Когда is_displayed() возвращает False
- Элемент скрыт через CSS:
display: noneилиvisibility: hidden - Элемент за пределами экрана:
position: absolute; left: -9999px - Элемент полностью прозрачен:
opacity: 0 - Элемент удалён из DOM
- Родительский элемент скрыт (наследуется)
# test_visibility.py
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("http://example.com")
element = driver.find_element(By.ID, "myElement")
if element.is_displayed():
print("Элемент виден на странице")
else:
print("Элемент скрыт")
driver.quit()
find_element() найдёт элемент, даже если он скрыт. is_displayed() нужен, чтобы убедиться в видимости.
Метод find_elements()
Ищет все элементы по локатору. Не выбрасывает исключение — возвращает пустой список [].
| Метод | Если не найден | Тип результата |
|---|---|---|
find_element() |
Выбрасывает NoSuchElementException |
WebElement |
find_elements() |
Возвращает пустой список [] |
list[WebElement] |
# test_find_elements.py
cards = driver.find_elements(By.CSS_SELECTOR, ".col-sm-4")
print(f"Найдено карточек: {len(cards)}")
for card in cards:
assert card.is_displayed(), f"Карточка скрыта: {card.text}"