Выполнение JavaScript
Выполнение произвольного JavaScript-кода в контексте браузера: evaluate, evaluate_handle, add_init_script, аргументы и возвращаемые значения.
Основы 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().