Python
Get_attribute в Selenium Python: примеры
get_attribute() в Selenium нужен, когда вы хотите получить не текст между тегами, а значение атрибута HTML-элемента: href у ссылки, src у картинки, value у поля ввода, class у блока, disabled у кнопки. Это частая задача в автотестах, парсинге открытой страницы и проверке интерфейса после клика или загрузки данных
Главная мысль простая: element.text отвечает на вопрос «что видит пользователь как текст», а element.get_attribute("...") отвечает на вопрос «что записано в HTML-атрибуте элемента». Если перепутать эти два способа, тест может проходить случайно или брать не те данные
Минимальный пример с ссылкой
from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.get("https://example.com")
link = browser.find_element(By.CSS_SELECTOR, "a")
href = link.get_attribute("href")
print(href)
browser.quit()
В этом примере Selenium открывает страницу, находит первую ссылку и забирает значение href. Если ссылка в HTML написана относительным путем, браузер часто вернет уже полный адрес. Поэтому в тестах лучше проверять не всю строку целиком, а важную часть адреса
assert "iana.org" in href
По этой теме полезно отдельно посмотреть Составьте еженедельное расписание занятий, чтобы расширить контекст и сравнить подходы
По этой теме полезно отдельно посмотреть Аннотации типов для декораторов в Python, чтобы расширить контекст и сравнить подходы
Чем атрибут отличается от текста элемента
У одного и того же элемента могут быть текст и атрибуты. Например, ссылка может показывать читателю одно, а вести совсем в другое место
<a href="/catalog/python" class="nav-link">Python</a>
link = browser.find_element(By.CSS_SELECTOR, ".nav-link")
print(link.text) # Python
print(link.get_attribute("href")) # полный адрес страницы каталога
print(link.get_attribute("class")) # nav-link
Если вы проверяете подпись кнопки, нужен .text. Если проверяете, куда ведет ссылка, какой файл указан в картинке или какое значение лежит в поле, нужен get_attribute()
Поле ввода и атрибут value
Для input и textarea текст часто хранится не как обычный текст узла, а как значение поля. Поэтому попытка взять .text может вернуть пустую строку
from selenium.webdriver.common.by import By
field = browser.find_element(By.NAME, "email")
field.clear()
field.send_keys("test@example.com")
value = field.get_attribute("value")
print(value)
Так удобно проверять, что поле действительно заполнилось, маска телефона сработала, автоподстановка поставила нужный город или форма не стерла значение после валидации
Атрибуты disabled, checked и selected
С булевыми атрибутами нужно быть внимательнее. В HTML кнопка может быть отключена через disabled, чекбокс отмечен через checked, опция выбрана через selected. Selenium может вернуть строку, пустое значение или None в зависимости от атрибута и состояния элемента
button = browser.find_element(By.CSS_SELECTOR, "button[type='submit']")
disabled = button.get_attribute("disabled")
print(disabled)
Для пользовательского состояния часто лучше использовать специальные методы Selenium
checkbox = browser.find_element(By.ID, "agree")
print(checkbox.is_selected())
print(button.is_enabled())
Практическое правило такое: get_attribute() подходит для HTML-значения, а is_selected() и is_enabled() лучше подходят для проверки поведения элемента как элемента интерфейса
Как дождаться элемента перед чтением атрибута
Частая ошибка новичка: страница еще не дорисовала элемент, а код уже пытается взять атрибут. В результате появляется NoSuchElementException, пустая строка или старое значение
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(browser, 10)
link = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "a.download")))
print(link.get_attribute("href"))
Если важно, чтобы пользователь мог нажать на элемент, используйте ожидание кликабельности
button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.buy")))
print(button.get_attribute("data-product-id"))
Такой код стабильнее, чем time.sleep(3), потому что ждет конкретное состояние страницы, а не просто паузу
Пример проверки картинки
У картинки обычно проверяют src, alt, размеры и класс. Минимальный тест может выглядеть так
image = browser.find_element(By.CSS_SELECTOR, "img.product-photo")
src = image.get_attribute("src")
alt = image.get_attribute("alt")
assert src.endswith(".webp") or src.endswith(".jpg")
assert alt.strip() != ""
Если на сайте важна доступность, пустой alt у смысловой картинки лучше считать ошибкой. Если картинка декоративная, пустой alt может быть нормальным решением, но это должно быть осознанно
Что делать, если атрибут возвращает None
None обычно означает, что такого атрибута у элемента нет. Это не всегда ошибка Selenium. Сначала откройте DevTools, найдите элемент и проверьте, действительно ли нужный атрибут есть в HTML
value = link.get_attribute("data-id")
if value is None:
print("У элемента нет data-id")
else:
print(value)
Если атрибут появляется после действия пользователя, сначала выполните действие, потом дождитесь изменения. Например, кликнули кнопку, дождались загрузки карточки и только после этого забрали data-status
Чек-лист перед использованием get_attribute
- выберите элемент точным локатором
- убедитесь, что элемент уже появился на странице
- проверьте имя атрибута в DevTools
- не путайте
.textиget_attribute("value") - для кнопок и чекбоксов используйте
is_enabled()иis_selected(), если проверяете поведение - обрабатывайте
None, если атрибут может отсутствовать - закрывайте браузер через
quit(), чтобы не оставлять процессы
Практика: проверить все ссылки в меню
Один из самых полезных учебных сценариев — пройти по ссылкам меню и убедиться, что у каждой есть адрес
links = browser.find_elements(By.CSS_SELECTOR, "nav a")
for link in links:
text = link.text.strip()
href = link.get_attribute("href")
print(text, href)
assert href, f"У ссылки {text!r} нет href"
Если меню рисуется JavaScript-кодом, сначала дождитесь появления пунктов. Иначе Selenium может найти пустой список или старую версию DOM
wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "nav a")))
В реальном тесте полезно отдельно проверять внешние и внутренние ссылки. Внутренняя ссылка должна вести на ваш домен или относительный путь, внешняя — на ожидаемый сервис. Так вы быстрее заметите случайную подмену адреса или битую кнопку
Практика: data-атрибуты в интерфейсе
В современных интерфейсах часто используют data-* атрибуты. Они удобны для тестов, потому что не зависят от текста кнопки и декоративных классов
<button data-testid="checkout-button" data-product-id="42">Купить</button>
button = browser.find_element(By.CSS_SELECTOR, "[data-testid='checkout-button']")
product_id = button.get_attribute("data-product-id")
assert product_id == "42"
Если вы пишете и frontend, и тесты, договоритесь о стабильных data-testid. Не цепляйтесь к классам вроде button_blue_big, если дизайнер может поменять их завтра
Мини-диагностика при странном результате
Если get_attribute() возвращает не то, что вы ожидали, проверьте три вещи. Во-первых, точно ли найден правильный элемент. Во-вторых, не меняется ли атрибут после загрузки страницы. В-третьих, не лежит ли нужное значение в свойстве, а не в HTML-атрибуте
Для диагностики можно вывести HTML элемента
print(element.get_attribute("outerHTML"))
Это не нужно оставлять в постоянном тесте, но при разборе ошибки помогает увидеть реальную разметку, с которой работает Selenium