Я уже прочитал документацию, но меня все еще смущает метод get_by_text
в драматургическом Python:
У меня есть небольшая демонстрация кода, в которой я пытаюсь получить селектор текста Sr. Enterprise Cloud & Snowflake Architect.
тогда я просто хочу знать природу этого селектора, это элемент div, диапазон или т. д.
from playwright.sync_api import sync_playwright
import os
my_path = os.getcwd()
html = open("l.html", "r", encoding = "utf-8").read()
with sync_playwright() as p:
chromium_path = f'{my_path}/chromium-1076/chrome-win/chrome.exe'
browser = p.chromium.launch(executable_path=chromium_path, headless=False)
page = browser.new_page()
page.set_content(html)
element = page.get_by_text("Sr. Enterprise Cloud & Snowflake Architect", exact=True)
tag_name = element.evaluate("el => el.tagName")
print(tag_name)
browser.close()
проблема, с которой я сталкиваюсь, заключается в нарушении строгого режима, которого я, честно говоря, не понимаю:
playwright._impl._api_types.Error: Error: strict mode violation: get_by_text("Sr. Enterprise Cloud & Snowflake Architect", exact=True) resolved to 2 elements:
1) <span aria-hidden = "true">…</span> aka get_by_text("Sr. Enterprise Cloud & Snowflake Architect").first
2) <span class = "visually-hidden">…</span> aka get_by_text("Sr. Enterprise Cloud & Snowflake Architect").nth(1)
=========================== logs ===========================
waiting for get_by_text("Sr. Enterprise Cloud & Snowflake Architect", exact=True)
Что я хочу знать, так это то, что метод get_by_text()
действительно возвращает локатор совпадающего текста или нет, и эта проблема, как ее решить, если это возможно.
page.get_by_text()
возвращает локатор , аналогичный page.locator()
(и многим другим методам), но с текстовым запросом.
Локаторы — это декларативный способ выбора элементов. Простой вызов page.get_by_text("selector")
ничего не даст — это просто декларация о намерениях. Таким образом, вызов переменной локатора element
немного вводит в заблуждение, поскольку ни один элемент еще не получен.
Позже, как только вы запустите element.evaluate()
, локатор начнет действовать. Playwright запускает выборку для локатора, чтобы найти соответствующие ему элементы, автоматически ожидая существования и действия, если это необходимо, и выполняет оценку в контексте браузера.
Следующая концепция, которая здесь задействована, — это строгий режим. По умолчанию Playwright выдает ошибку, если вы пытаетесь выполнить одноэлементное действие, когда локатор разрешается в несколько элементов. Эта ошибка является мерой безопасности, позволяющей избежать ситуации, когда на странице появляется новый элемент, в результате чего ваш предыдущий выбор автоматически переключается на непредусмотренную цель. Ошибка предлагает вам быть более конкретным в запросе локатора и предлагает код для устранения неоднозначности множественных совпадений.
Вы можете отключить строгий режим и всегда выбирать первый элемент, но это не рекомендуется. Я бы посмотрел на l.html
и устранил неоднозначность, основываясь на более широком контексте того, что вы пытаетесь выполнить, и доступных атрибутах элементов, родительском дереве и поддереве. Не существует универсального способа устранения неоднозначности элементов.
Кстати, немного необычно вытягивать tagName
из элемента. В 99% случаев в этом нет необходимости, так что либо это заглушка для какого-то другого действия, либо вы преследуете антипаттерн. Возможно, вы захотите предоставить некоторый контекст высокого уровня для того, что вы пытаетесь сделать.
Я не думаю, что для этого вам нужно получать имя тега. Скорее всего, вы можете включить это условие в свой запрос. Я предлагаю отредактировать ваш пост, чтобы прояснить ваш полный вариант использования. Имеет ли остальная часть моего поста смысл для вас и решает ли ваши основные вопросы о локаторах?
Спасибо за ваш ответ, вариант использования заключается в том, что мне нужно обнаружить определенные ключевые слова именно в DOM, и они не должны быть тегом <code>, поэтому я получаю имя тега для проверки.