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

Основы evaluate

page.evaluate("document.title")

Выполняет JavaScript-код на странице и возвращает результат как Python-объект.

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()
    page.goto("https://example.com")
    title = page.evaluate("document.title")
    print(title)  # "Example Domain"
    browser.close()

page.evaluate("(a, b) => a + b", 1, 2) — аргументы

Можно передавать аргументы в JavaScript-функцию. Они сериализуются в JSON.

result = page.evaluate("(a, b) => a + b", 1, 2)
print(result)  # 3

page.evaluate("({name}) => name", {"name": "test"}) — объекты

При передаче объектов можно использовать деструктуризацию в JavaScript.

result = page.evaluate(
    "({name}) => name",
    {"name": "test"}
)
print(result)  # "test"

JSHandle

page.evaluate_handle("() => document.body")

Возвращает JSHandle — ссылку на JavaScript-объект, которая позволяет взаимодействовать с ним без сериализации. Полезно для работы с DOM-элементами и глобальными объектами.

body_handle = page.evaluate_handle("() => document.body")
tag = body_handle.evaluate("el => el.tagName")
print(tag)  # "BODY"
body_handle.dispose()

page.evaluate_handle("window")

Получение ссылки на глобальный объект window.

window_handle = page.evaluate_handle("window")
location = window_handle.evaluate("win => win.location.href")

Методы evaluate в разных контекстах

frame.evaluate()

Выполнение JS в конкретном фрейме.

frame = page.frame("iframe-name")
result = frame.evaluate("document.title")

locator.evaluate()

Выполнение JS для конкретного элемента, найденного через локатор.

text = page.get_by_role("button").evaluate(
    "el => el.textContent"
)

element_handle.evaluate()

Выполнение JS для конкретного ElementHandle.

handle = page.query_selector("button")
text = handle.evaluate("el => el.innerText")

Асинхронные вызовы

page.evaluate("async () => await fetch('/api')")

Поддерживаются асинхронные функции. Playwright ожидает разрешения промиса.

data = page.evaluate("""
    async () => {
        const res = await fetch('/api/data');
        return res.json();
    }
""")

page.evaluate(() => localStorage.getItem('token'))

Чтение данных из хранилищ браузера.

token = page.evaluate("() => JSON.parse(localStorage.getItem('token'))")

page.evaluate(() => new Promise(...))

Работа с промисами — Playwright автоматически ожидает их разрешения.

result = page.evaluate("""
    () => new Promise(resolve => {
        setTimeout(() => resolve('Готово!'), 1000)
    })
""")
print(result)  # "Готово!" (через 1 секунду)

add_init_script — скрипты до загрузки

page.add_init_script("() => { window.__TEST__ = true }")

Регистрирует скрипт, который выполняется перед каждым navigational загрузкой страницы. Полезно для установки глобальных переменных, моков или переопределений.

page.add_init_script("""
() => {
    window.__TEST__ = true;
    window.__ENV = 'testing';
    Date.now = () => 1700000000000;
}
""")
page.goto("https://example.com")
is_test = page.evaluate("window.__TEST__")  # True

Примечание: Скрипты, добавленные через add_init_script, выполняются до загрузки любых других скриптов на странице, включая встроенные. Это идеальный способ для подмены глобальных объектов.

Изоляция контекста

page.evaluate() выполняется в контексте браузера, но имеет доступ к DOM и JavaScript-окружению страницы. Python-объекты, переданные как аргументы, сериализуются в JSON.

# Все типы, сериализуемые в JSON, поддерживаются
page.evaluate("data => console.log(data)", {
    "string": "текст",
    "number": 42,
    "bool": True,
    "list": [1, 2, 3],
    "nested": {"key": "value"}
})

# Функции и циклические ссылки НЕ поддерживаются
# Для передачи функций используйте expose_function

Важно: page.evaluate() не может вернуть функции, символы или объекты с циклическими ссылками. Если нужно сохранить ссылку на JS-объект, используйте page.evaluate_handle().