Фреймы
Работа с iframe, вложенными фреймами и межфреймовым взаимодействием
Что такое фреймы в Playwright?
Фреймы (iframe) — это встроенные HTML-документы внутри основной страницы. Playwright предоставляет удобные методы для работы с ними. Каждый Frame имеет собственную DOM-модель, доступную через те же локаторы, что и у Page.
Получение фрейма
Фрейм можно получить по CSS-селектору, имени или URL:
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")
# По CSS-селектору (FrameLocator)
frame_locator = page.frame_locator("iframe#content")
# По имени
frame = page.frame(name="main-frame")
# По URL
frame = page.frame(url="https://example.com/embedded")
FrameLocator — поиск внутри фрейма
page.frame_locator() возвращает FrameLocator, который позволяет искать элементы внутри iframe как в основной странице:
# Найти кнопку внутри iframe
frame = page.frame_locator("iframe#chat")
button = frame.get_by_role("button", name="Отправить")
button.click()
# Заполнить поле внутри фрейма
frame.locator("#message").fill("Привет!")
Прямой доступ к фрейму (Frame)
Методы page.frame() возвращают объект Frame, который поддерживает все те же методы, что и Page:
frame = page.frame(name="content")
frame.fill("#search", "query")
frame.get_by_text("Найти").click()
frame.wait_for_load_state("networkidle")
Выполнение JavaScript во фрейме
frame = page.frame(name="content")
title = frame.evaluate("() => document.title")
print(f"Заголовок фрейма: {title}")
Список всех фреймов на странице
for frame in page.frames:
print(f"Имя: {frame.name}, URL: {frame.url}")
Вложенные фреймы (child_frames)
Фреймы могут содержать вложенные фреймы. Свойство frame.child_frames возвращает дочерние фреймы:
def print_frames(frame, indent=0):
print(" " * indent + f"Frame: {frame.name} ({frame.url})")
for child in frame.child_frames:
print_frames(child, indent + 2)
print_frames(page)
Цепочка frame_locator для вложенных фреймов
Для глубоко вложенных iframe можно выстраивать цепочки:
# Внешний iframe -> внутренний iframe -> элемент
button = page.frame_locator("iframe#outer") \
.frame_locator("iframe#inner") \
.get_by_role("button", name="OK")
button.click()
Ожидание селектора во фрейме
frame = page.frame(name="content")
frame.wait_for_selector(".loaded", state="visible", timeout=10000)
Frame.content() и Frame.title()
frame = page.frame(name="main")
html = frame.content()
title = frame.title()
print(f"Заголовок: {title}")
События фреймов
Playwright генерирует события при добавлении, удалении и навигации фреймов:
def on_frame_attached(frame):
print(f"Фрейм добавлен: {frame.url}")
def on_frame_detached(frame):
print(f"Фрейм удалён: {frame.url}")
def on_frame_navigated(frame):
print(f"Фрейм обновлён: {frame.url}")
page.on("frameattached", on_frame_attached)
page.on("framedetached", on_frame_detached)
page.on("framenavigated", on_frame_navigated)
Полный пример с фреймами
import re
from playwright.sync_api import sync_playwright
def test_iframe():
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("https://example.com/with-iframe")
# Работа с iframe по селектору
frame = page.frame_locator("iframe#payment")
frame.get_by_placeholder("Номер карты").fill("4111111111111111")
frame.get_by_placeholder("MM/YY").fill("12/28")
frame.get_by_role("button", name="Оплатить").click()
# Проверка основного фрейма
main_frame = page.frame(name="main")
assert main_frame.get_by_text("Оплата прошла").is_visible()
browser.close()
test_iframe()