Selenium + Python: я не могу получить доступ к элементу в iframe после использования driver.switch_to.frame(iframe_id)

Я использую python 3 и селен, чтобы делать некоторые веб-скрейпинги. Обычно у меня нет проблем, но на этот раз мне нужно получить доступ к элементам в iframe.

Я читал и решил следовать советам и переключать кадры, а затем искать элементы.

Итак, здесь я переключаю кадр:

iframe = driver.find_element(By.XPATH, "//iframe[contains(@id, 'ext-gen')]")
iframe_id = str(iframe.get_attribute('id'))

driver.switch_to.frame(iframe_id)

Однако я не могу получить элементы в этом кадре.

input_project = driver.find_element(By.XPATH, '//*[contains(@id, "b_s4_l1s4_ctl00_project_i")]')

Трассировка стека ошибок:

Traceback (most recent call last):

 input_project = driver.find_element(By.XPATH, '//*[contains(@id, "b_s4_l1s4_ctl00_project_i")]')

  File ~\AppData\Local\anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py:831 in find_element
    return self.execute(Command.FIND_ELEMENT, {"using": by, "value": value})["value"]

  File ~\AppData\Local\anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py:440 in execute
    self.error_handler.check_response(response)

  File ~\AppData\Local\anaconda3\lib\site-packages\selenium\webdriver\remote\errorhandler.py:245 in check_response
    raise exception_class(message, screen, stacktrace)

NoSuchElementException: Unable to locate element: //*[contains(@id, "b_s4_l1s4_ctl00_project_i")]

не уверен, что это опечатка в вашем вопросе или вы действительно это делаете, но вы ищете элемент ввода, используя тег iframe. (input_project = driver.find_element(By.XPATH, '//iframe[contains(@id, "b_s4_l1s4_ctl00_project_i")]')

levangode 25.04.2023 18:02

@LevanGoderdzishvili, спасибо, что указали на это. Я изменил свой первоначальный пост. Однако это не решает проблему. У вас есть идеи, что я делаю неправильно здесь? Спасибо!

Candy Deck 25.04.2023 18:52

трудно определить проблему без HTML. Это публичный сайт? Предоставьте ссылку или сделайте pastebin с содержимым HTML

levangode 25.04.2023 19:12

Во-первых, попробуйте driver.switch_to.frame(iframe). Кроме того, попробуйте использовать ожидания selenium-python.readthedocs.io/waits.html, потому что iframe или элемент могут быть еще не загружены в DOM к моменту выполнения ваших методов.

levangode 25.04.2023 19:17

@LevanGoderdzishvili, Большое спасибо за помощь! присмотревшись к html, я обнаружил, что внутри iframe был еще один фрейм. Переключение на этот второй кадр сделало элементы видимыми! :) Еще раз спасибо за ваше время

Candy Deck 25.04.2023 21:31
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я не уверен, почему ты это делаешь

iframe = driver.find_element(By.XPATH, "//iframe[contains(@id, 'ext-gen')]")
iframe_id = str(iframe.get_attribute('id')) <<< why?

driver.switch_to.frame(iframe_id)

У вас уже есть элемент IFRAME в iframe, просто используйте его при переключении кадров. Также добавьте ожидание, чтобы убедиться, что кадр готов.

iframe = driver.find_element(By.XPATH, "//iframe[contains(@id, 'ext-gen')]")
wait = WebDriverWait(driver, 10)
wait.until(EC.frame_to_be_available_and_switch_to_it(iframe))
iframe = driver.find_element(By.XPATH, "//iframe[contains(@id, 'ext-gen')]") wait = WebDriverWait(driver, 10) wait.until(EC.frame_to_be_available_and_switch_to_it(iframe)‌​) дает мне: Out[57]: True поэтому я думаю, что переключился на этот iframe. Однако я все еще не могу получить доступ к элементам в этом iframe
Candy Deck 25.04.2023 21:16

Можно ссылку на страницу? Я предполагаю, что мы либо переключаемся на неправильный IFRAME, либо может быть другой IFRAME или теневой корень для переключения, но я не могу сказать, не видя страницы или дополнительной информации.

JeffC 25.04.2023 21:30

Я нашел то, что пропустил! Фрейм находился внутри iframe. Так что мне нужно было переключиться дважды iframe = driver.find_element(By.XPATH, "//iframe[contains(@id, 'ext-gen')]") wait = WebDriverWait(driver, 10) wait.until(EC.frame_to_be_available_and_switch_to_it(iframe)‌​) frame2 = driver.find_element(By.XPATH, "//frame[contains(@id, 'contentContainerFrame')]") wait = WebDriverWait(driver, 10) wait.until(EC.frame_to_be_available_and_switch_to_it(frame2)‌​) project = driver.find_element(By.ID, "b_s4_l1s4_ctl00_project_i") project.send_keys("999333")

Candy Deck 25.04.2023 21:34

Вы можете удалить второй экземпляр wait = WebDriverWait(driver, 10). Как только переменная wait определена, вы можете повторно использовать ее столько раз, сколько вам нужно.

JeffC 25.04.2023 21:38

Другие вопросы по теме