Как в Playwright for Python получить дескриптор элементов из фрейма (iframe)?

Я успешно использовал Playwright в Python для получения элементов со страницы. Теперь я столкнулся с проблемой получения элементов из документа, встроенного в iframe . В качестве примера я использовал страницу w3schools, объясняющую элемент , который отображает результат в iframe. Я пытаюсь найти дескриптор для этого <option> элемент из iframe.

«Обычный» способ получить элемент на странице с помощью page.querySelector() не может получить elementHandle, это просто печатает:

      with sync_playwright() as p:
    for browser_type in [p.chromium, p.firefox, p.webkit]:
        browser = browser_type.launch(headless=False)
        page = browser.newPage()
        page.goto('https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_option')
        element = page.querySelector('select')
        print(type(element))
        browser.close()

Сначала я попытался явно получить дескриптор для iframe, но это дает тот же результат ( <class 'NoneType'>):

      with sync_playwright() as p:
    for browser_type in [p.chromium, p.firefox, p.webkit]:
        browser = browser_type.launch(headless=False)
        page = browser.newPage()
        page.goto('https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_option')      
        iframe = page.querySelector('iframe')
        element = iframe.querySelector('select')
        print(type(element))
        browser.close()

Как я могу получить контент из iframe?

3 ответа

Решение

Оказалось, что я был близок, но для правильного получения iframe мне нужно было вызвать contentFrame() метод.

Возвращает фрейм содержимого для дескрипторов элементов, ссылающихся на узлы iframe, или null иначе

Потом, querySelector() вернет соответствующий elementHandle просто хорошо:

      with sync_playwright() as p:
    for browser_type in [p.chromium, p.firefox, p.webkit]:
        browser = browser_type.launch(headless=False)
        page = browser.newPage()
        page.goto('https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_option')
        iframe = page.querySelector('iframe').contentFrame()
        element = iframe.querySelector('select')
        print(type(element))
        print(element.innerHTML())
        browser.close()

успешно печатает

      <class 'playwright.sync_api.ElementHandle'>

  <option value="volvo">Volvo</option>
  <option value="saab">Saab</option>
  <option value="opel">Opel</option>
  <option value="audi">Audi</option>

Примечание: если есть несколько окон iframe, вы можете просто использовать атрибут при получении дескриптора. Чтобы получить iframe по его id в приведенном выше примере, например, используйте

      iframe = page.querySelector('iframe[id=\"iframeResult\"]').contentFrame()

querySelector вернет ElementHandle. В этом случае это будет iFrameа как элемент страницы. Если вы хотите получить frame из этого элемента вам нужно позвонить contentFrame, а затем работайте над этим кадром.

      iframe = page.querySelector('#iframeResult').contentFrame()
element = iframe.querySelector('select')
print(type(element))

Версия 1.22

      page.frame_locator("iframe#iframeResult").locator("select#cars")

https://playwright.dev/python/docs/api/class-elementhandle#element-handle-content-frame

Использование ElementHandle не рекомендуется, вместо этого используйте объекты Locator и веб-утверждения.

https://playwright.dev/python/docs/api/class-framelocator

Пример кода с использованиемframe_locator

      from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()
    page.goto(
        "https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_option", timeout=0
    )
    page.wait_for_selector("iframe#iframeResult")

    select = page.frame_locator("iframe#iframeResult").locator("select#cars")

    print(select.inner_html())
    # <option value="volvo">Volvo</option>
    # <option value="saab">Saab</option>
    # <option value="opel">Opel</option>
    # <option value="audi">Audi</option>

    print(select.inner_text())
    # Volvo
    # Saab
    # Opel
    # Audi

    browser.close()
Другие вопросы по тегам