Playwright Python — справочник На главный сайт

Обзор ElementHandle

ElementHandle — это представление DOM-элемента в Playwright. В отличие от Locator, который использует ленивое вычисление и автоматическое ожидание, ElementHandle даёт прямой доступ к элементу и его методам. Обычно ElementHandle получают через page.query_selector() и page.query_selector_all().

Важно: Playwright рекомендует использовать Locator вместо ElementHandle в большинстве случаев. Locator автоматически ожидает появления элемента и повторяет действия при неудаче. ElementHandle не имеет такого поведения.

Получение ElementHandle

# Получить первый элемент, соответствующий селектору
button = page.query_selector("button.submit")

# Получить все элементы
items = page.query_selector_all("li")

# Внутри фрейма
frame = page.frame("main")
header = frame.query_selector("h1")

Основные действия

# Клик по элементу
button.click()

# Заполнение текстового поля
input_element.fill("Hello, World!")

# Получение текстового содержимого
text = element.text_content()
inner = element.inner_text()
html = element.inner_html()

# Получение атрибута
href = element.get_attribute("href")

Проверка состояния

# Проверка видимости
element.is_visible()
element.is_hidden()

# Проверка доступности
element.is_enabled()

# Проверка состояния чекбокса/radio
element.is_checked()

Продвинутые взаимодействия

# Наведение мыши
element.hover()

# Фокус
element.focus()

# Нажатие клавиши
element.press("Enter")
element.press("Control+a")

# Отправка пользовательского события
element.dispatch_event("click", "{ bubbles: true }")

# Скролл до элемента
element.scroll_into_view_if_needed()

# Выделение текста
element.select_text()

# Загрузка файлов
element.set_input_files("file.txt")
element.set_input_files(["file1.pdf", "file2.pdf"])

Координаты и размеры

# Получение bounding box (x, y, width, height)
box = element.bounding_box()
if box:
    print(f"X: {box['x']}, Y: {box['y']}")
    print(f"Width: {box['width']}, Height: {box['height']}")

Выполнение JavaScript на элементе

Метод evaluate() выполняет JS-функцию на переданном элементе, а evaluate_handle() возвращает JSHandle.

# Выполнение JS — возвращает Python-значение
text = element.evaluate("el => el.textContent")
styles = element.evaluate("el => window.getComputedStyle(el)")
rect = element.evaluate("el => el.getBoundingClientRect()")

# evaluate_handle — возвращает JSHandle
js_handle = element.evaluate_handle("el => el.style")
color = js_handle.get_property("color")
print(await color.json_value())

Скриншот элемента

# Скриншот конкретного элемента
element.screenshot(path="element.png")

# Скриншот с кастомными опциями
element.screenshot(
    path="element.png",
    type="jpeg",
    quality=80,
    omit_background=True
)

Ожидание состояния элемента

Метод wait_for_element_state() ожидает, пока элемент не достигнет указанного состояния. В отличие от автоматического ожидания Locator, здесь ожидание явное.

# Ожидание видимости
element.wait_for_element_state("visible")
# Ожидание скрытия
element.wait_for_element_state("hidden")
# Ожидание стабильности (не анимируется)
element.wait_for_element_state("stable")
# Ожидание включения
element.wait_for_element_state("enabled")
# Ожидание отключения
element.wait_for_element_state("disabled")

Совет: Если вам нужно просто подождать появления элемента на странице, используйте page.wait_for_selector(css) — он вернёт ElementHandle, дождавшись появления элемента в DOM.

ElementHandle vs Locator

ХарактеристикаElementHandleLocator
АвтоожиданиеНет (кроме wait_for_element_state)Автоматическое
Повтор при неудачеНетЕсть (retry)
Ленивое вычислениеНет (жёсткая ссылка на элемент)Да (поиск при действии)
Stale-элементыУстаревают при изменении DOMАвтоматически переищет
ИспользованиеНизкоуровневые сценарии, JS-интеграцияОсновной API для тестов
ПроизводительностьБыстрее для однократных операцийНебольшие накладные расходы

Когда использовать ElementHandle

Несмотря на рекомендацию использовать Locator, есть сценарии, где ElementHandle удобнее:

  • Однократные операции — нужно быстро прочитать атрибут или текст без повторных попыток
  • Выполнение JS на элементеevaluate() и evaluate_handle() работают напрямую с ElementHandle
  • Работа с фреймами — некоторые сценарии с iframe требуют ElementHandle
  • Кастомные событияdispatch_event() для нестандартных событий
  • Скриншоты конкретных элементов — быстрый скриншот без автоожидания

Внимание: ElementHandle может стать "stale" (устаревшим), если DOM изменился после его получения. При каждом изменении страницы нужно запрашивать новый ElementHandle. Locator лишён этого недостатка.

Примеры

Чтение данных из таблицы

def get_table_data(page):
    rows = page.query_selector_all("table tr")
    data = []
    for row in rows:
        cells = row.query_selector_all("td, th")
        data.append([cell.inner_text() for cell in cells])
    return data

Проверка CSS-свойств

def test_button_color(page):
    page.goto("https://example.com")
    btn = page.query_selector("button.primary")
    color = btn.evaluate("el => window.getComputedStyle(el).color")
    assert color == "rgb(255, 0, 0)"

Скриншот динамического элемента

def test_captcha_screenshot(page):
    page.goto("https://example.com/login")
    captcha_img = page.query_selector("img.captcha")
    captcha_img.screenshot(path="captcha.png")