Почему использование явного ожидания внутри кадра вызывает ошибку тайм-аута, но использование time.sleep работает?

Этот код работает:

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys

# Define browser
browser = webdriver.Firefox(executable_path=r"path\geckodriver.exe")

# Open website
browser.get('website')

# Get "before" window handle
window_before = browser.window_handles[0]

# Login
searchElem = browser.find_element_by_css_selector('#login')
searchElem.send_keys('login')
searchElem2 = browser.find_element_by_css_selector('#password')
searchElem2.send_keys('password')
searchElem2.submit()

# Next page loads
time.sleep(2)
browser.switch_to.frame(3)
searchElem3 = browser.find_element_by_name('Element')
searchElem3.click()
searchElem3.send_keys('Hello')
searchElem3.send_keys(Keys.ENTER)

Но я читал, что более эффективно использовать «явное ожидание» вместо «time.sleep», поэтому я попробовал это, но этот код выдает ошибку TimeoutExceptionError:

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys

# Define browser
browser = webdriver.Firefox(executable_path=r"path\geckodriver.exe")

# Open website
browser.get('website')

# Get "before" window handle
window_before = browser.window_handles[0]

# Login
searchElem = browser.find_element_by_css_selector('#login')
searchElem.send_keys('login')
searchElem2 = browser.find_element_by_css_selector('#password')
searchElem2.send_keys('password')
searchElem2.submit()

# Next page loads
try:
    searchElem3 = WebDriverWait(browser, 10).until(EC.frame_to_be_available_and_switch_to_it(By.ID, "Element"))
finally:
    browser.quit()
searchElem3.click()
searchElem3.send_keys('Hello')
searchElem3.send_keys(Keys.ENTER)

Есть идеи, что я делаю не так? Я также пробовал несколько способов найти элемент безрезультатно (вместо By.ID, используя XPATH и т. Д.)

РЕДАКТИРОВАТЬ: Чтобы уточнить, «frame (3)» и «Element» - это один и тот же кадр, на который я пытаюсь переключиться. Во второй попытке я пытался использовать webdriverwait вместо time.sleep.


person presentformyfriends    schedule 06.05.2020    source источник


Ответы (1)


Это потому, что во второй попытке вы не переключаетесь на фрейм до того, как дождетесь элемента. Selenium ждал 10 секунд для элемента в родительском окне и не смог найти его в родительском окне. Следовательно, сбой с таймаутом.

Но в вашем 1-м подходе вы переключаетесь на фрейм usig browser.switch_to.frame(3), и селен может успешно найти элемент в 3-м фрейме.

Попробуйте добавить явное ожидание в 3-м кадре.

person supputuri    schedule 06.05.2020
comment
Извините, я должен был быть более ясным, элемент ID и фрейм (3) - это один и тот же фрейм. Поэтому вместо того, чтобы ждать этого кадра time.sleep, я пытался использовать явное ожидание. Я использовал Element, потому что он выдает ошибку типа bool всякий раз, когда я использую 3 или frame (3) - person presentformyfriends; 07.05.2020
comment
Я все равно попробовал, и он выдал эту ошибку: TypeError: __init __ () принимает 2 позиционных аргумента, но было дано 3 - person presentformyfriends; 07.05.2020
comment
измените его на searchElem3 = WebDriverWait (browser, 10) .until (EC.frame_to_be_available_and_switch_to_it ((By.ID, Element))) ` - person supputuri; 07.05.2020
comment
Я попробовал это с дополнительными скобками и выбросил TimeoutExceptionError. Итак, я предполагаю, что проблема в том, что при нажатии кнопки «Отправить» в: searchElem2.submit() загружается следующее окно, но программа ожидает, когда фрейм элемента станет доступным в предыдущем окне? Это правильно? Итак, перед тем, как ждать фрейма, следует ли мне сказать ему, чтобы он дождался определенного окна? Я не знаю, как это сделать. - person presentformyfriends; 08.05.2020