неявные или явные ожидания в селене не работают надежно по времени. - PullRequest
1 голос
/ 25 октября 2019

У меня есть некоторый код селена для входа в jupyterlab (работает локально). Без ожидания происходит сбой, так как он пытается найти текстовое поле ввода пароля, прежде чем он существует. Поэтому я попытался использовать явное ожидание, так как это кажется самым чистым решением, но оно работает хаотично. Неявные ожидания никогда не работают, кажется, что веб-сервер блокируется на 10 секунд перед загрузкой страницы, поэтому всегда происходит сбой. time.sleep всегда работает, однако загружает страницу и затем ждет 10 секунд, прежде чем ввести пароль, который неэффективен и менее чист, чем методы ожидания селена, которые, как я понимаю, ждут до 10 секунд, но останавливают ожидание, как только элемент становитсядоступный. Что я сделал не так?

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.wait import WebDriverWait
  1. Явное ожидание - иногда работает

    driver = webdriver.Firefox()
    driver.get(f"http://localhost:8888")
    wait = WebDriverWait(driver, 10)
    password_input = wait.until(ec.presence_of_element_located((By.ID, "password_input")))
    password = "my_password"
    password_input.send_keys(password + Keys.RETURN)
    

    иногда я получаю сообщение об ошибке:

    selenium.common.exceptions.ElementNotInteractableException: Сообщение: Элемент недоступен с клавиатуры

  2. Неявное ожидание - иногда ошибки

    driver = webdriver.Firefox()
    driver.get(f"http://localhost:8888")
    driver.implicitly_wait(10)
    password_input = driver.find_element_by_css_selector("password_input")
    password = "my_password"
    password_input.send_keys(password + Keys.RETURN)
    

    иногда я получаю ошибку:

    selenium.common.exceptions.ElementNotInteractableException: Сообщение: элемент недоступен с клавиатуры

  3. time.sleep - всегда работает

    driver = webdriver.Firefox()
    driver.get(f"http://localhost:8888")
    time.sleep(10)
    password_input = driver.find_element_by_id("password_input")
    password = "my_password"
    password_input.send_keys(password + Keys.RETURN)
    

    Хотя это всегда работает, это бесполезно тратит время. И метод ожидания селена действительно должен работать.

Что я делаю не так?

1 Ответ

1 голос
/ 25 октября 2019

Хотя Как разрешить ElementNotInteractableException: Элемент не отображается в веб-драйвере Selenium? технически является дубликатом, он решает эту проблему для Java и всегда раздражает, когда дубликат предназначен для другого языка, поэтому янапишу этот ответ для Python.


Метод ec.presence_of_element_located(...) просто проверяет наличие элемента в объектной модели документа. Это не гарантирует, что элемент является чем-то, с чем пользователь может взаимодействовать. Другой элемент может перекрывать его или элемент может быть скрыт от просмотра на короткое время, прежде чем вы вызовете password_input.send_keys(...).

Ожидание, пока элемент «кликабелен», обычно является лучшим решением:

driver = webdriver.Firefox()
driver.get(f"http://localhost:8888")
wait = WebDriverWait(driver, 10)

# waiting until element is "clickable" means user can interact with
# it, and thus send_keys(...) can simulate keyboard interaction.
password_input = wait.until(ec.element_to_be_clickable((By.ID, "password_input")))

password = "my_password"
password_input.send_keys(password + Keys.RETURN)
...