Selenium Python - почему StaleElementReferenceException, а не NoSuchElement и как ловить - PullRequest
0 голосов
/ 27 апреля 2020

Я работаю над куском кода для автоматизации процесса входа в систему. Процесс состоит из заполнения имени пользователя на первой странице, нажатия кнопки и перехода ко второй странице, где я заполняю pw и нажимаю вторую кнопку. Веб-страница иногда видит много трафика c и выдает сообщение «Попробуйте позже ...» после нажатия на первую страницу. Чтобы позаботиться об этом, я добавил al oop, чтобы продолжать нажимать до тех пор, пока мы не перейдем на следующую страницу.

Как только я перехожу на следующую страницу, я все еще в это время 1026 *. Тем не менее, я ожидал, что поиск сообщения «Попробуйте позже» приведет к NoSuchElementException и, следовательно, нарушит l oop, но я получаю StaleElementReferenceException . Я понимаю, что, поскольку я перешел на другую страницу, этот элемент «Попробуйте позже» больше не находится в DOM.

Почему возникает исключение StaleElementReferenceException вместо NoSuchElementException? Если значение traffi c на веб-странице низкое, сообщение «Повторить позже позже» никогда не генерируется, а исключение NoSuchElementException исключает прерывание л oop. Как только сообщение появится один раз, StaleElement. Отслеживает ли Selenium ссылки на элементы, даже если мы не храним их в переменной? Если да, то как мы можем его удалить?

Первоначально я пытался , за исключением StaleElementReferenceException: , чтобы перехватить это исключение. Но ничего не происходит. Код, наконец, переходит на следующую страницу, но продолжает работать с l oop, ломая исключение StaleElementReferenceException (строка 4). Как мне поймать это исключение? Я просмотрел, думаю, все связанные вопросы, но не нашел рабочего ответа.

РЕДАКТИРОВАТЬ 1 I Я знаю, что нашел другие примеры здесь на SO, где люди используют except StaleElementReferenceException: Однако, это не работает в моем коде ниже. Код продолжает зацикливаться до тех пор, пока ему не удастся перейти на следующую страницу, но затем прерывает исключение устаревшего элемента.

while True:
    try:
        #looking for "try again later" message
        WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.XPATH, "//[@id='uiview']/ui-view/div/div[1]/div[1]/ui-view/div/div[2]/div/div[2]/form/div[3]/p")))
        #if it finds the element it clicks the login button.
        login_butn_1.click()
        print("clicked")

        #if logging in works; no "try again later" element, so we can break the loop
    except NoSuchElementException:
        print("no such element")
        break
    #Sometimes loading time is too long for "try again later"... message too appear and locating that element times out
    #Need to reselect the button to be able to click it
    except TimeoutException:           
        webdriver.ActionChains(self.driver).move_to_element(login_butn_1).click(login_butn_1).perform()
        print("time out")

    except StaleElementReferenceException:
        print("stale element exception")
        break

1 Ответ

0 голосов
/ 27 апреля 2020

Устаревшее означает старое, распавшееся, больше не свободно sh. Устаревший элемент означает старый элемент или более недоступный элемент. Предположим, что есть элемент, который находится на веб-странице, на которую ссылается как WebElement в WebDriver. Если DOM изменяется, то WebElement становится устаревшим. Если мы пытаемся взаимодействовать с элементом, который является устаревшим, то генерируется исключение StaleElementReferenceException.

Это нормально, когда по умолчанию выполняется опрос состояния элемента, поскольку я помню, что 500 мс это может произойти. Вы можете добавить это также в вашем случае, как если бы логически «элемент не в DOM» означает, что нет. Или добавьте дополнительное ожидание, потому что через несколько миллисекунд можно обновить sh и присутствовать.

Попробуйте добавить дополнительное ожидание или просто поместите его в try {} catch {} и выполните refre sh для элемента, что означает попытайтесь инициализировать его снова element = driver.find_element(By.XPATH, '//[@id='uiview']/ui-view/div/div[1]/div[1]/ui-view/div/div[2]/div/div[2]/form/div[3]/p"]')

Примечание refre sh элемента может вызвать исключение

...