Вопрос-Ответ

How can I select a html element no matter what frame it is in in selenium?

Как я могу выбрать html-элемент независимо от того, в каком фрейме он находится в selenium?

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

Возможно ли каким-либо образом выбрать элемент в некотором (под-) iframe в (python) selenium без предварительного выбора iframes? Есть ли способ каким-то образом "зациклить" каждый iframe и проверить, где найти мой элемент ...?

И как это сделать в случае, если элементы, html-материалы и iframes могут вот-вот загружаться ...?

Переведено автоматически
Ответ 1

Нет, невозможно взаимодействовать с каким-либо WebElement внутри <iframe> через Selenium без переключения на соответствующий iframe.

Причина :

При загрузке страницы фокус Selenium по умолчанию остается на верхнем окне. Верхнее окно содержит другие <iframes> и наборы фреймов. Итак, когда нам нужно взаимодействовать с WebElement, который находится внутри iframe, мы должны переключиться на соответствующий <iframe> с помощью одного из нижеперечисленных методов :


Методы переключения фреймов :

Мы можем переключиться на фреймы тремя способами.

По имени фрейма :

Name атрибут iframe, с помощью которого мы можем переключаться на него.

Пример:

driver.switch_to.frame("iframe_name")

По идентификатору фрейма :

ID атрибут iframe, с помощью которого мы можем переключиться на него.

Пример:

driver.switch_to.frame("iframe_id")

По индексу фрейма :

Предположим, что если на странице 10 фреймов, мы можем переключиться на iframe, используя индекс.

Пример:

driver.switch_to.frame(0)
driver.switch_to.frame(1)

Возврат к основному фрейму :

Мы можем вернуться к основному фрейму, используя default_content() или parent_frame()

Пример:

driver.switch_to.default_content()
driver.switch_to.parent_frame()

Лучший подход к переключению фреймов:

Лучшим способом переключения фреймов будет индуцировать WebDriverWait доступность предполагаемого фрейма с помощью expected_conditions set to frame_to_be_available_and_switch_to_it следующим образом :


  • Через идентификатор фрейма:


     WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.ID,"id_of_iframe"))


  • Через имя фрейма:


     WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.NAME,"name_of_iframe")))


  • Через Frame Xpath:


     WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"xpath_of_iframe")))


  • Through Frame CSS:


     WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"css_of_iframe")))



Reference

You can find a relevant detailed discussion in:

Ответ 2

Writing your own recursive finder should be easy enough. Apologies, don't know python but in Java it would be something like:

public void findInAllFrames(WebElement e, String targetIdStr) {

List<WebElement> l = e.findElements(By.tagName("iframe"));

for(int inx=0; inx<l.size(); inx++) {
List<WebElement> targets = l.get(inx).findElements(By.id(targetIdStr));
if(targets.size()>0) {
// Do something with your targets
}

findInAllFrames(l.get(inx), targetIdStr);
}
}
python selenium selenium-webdriver