Не удается исправить StaleElementReferenceException (элемент не прикреплен к документу)

В настоящее время я пытаюсь сделать некоторое полотно Selenium, но продолжаю сталкиваться с этой ошибкой:

StaleElementReferenceException: Сообщение: ссылка на устаревший элемент: элемент не прикреплен к документу страницы

Код должен на http://www.grownjkids.gov/ParentsFamilies/ProviderSearch непрерывно нажимать следующую кнопку (">") результатов и очищать результаты со всех страниц в цикле. Он будет делать это правильно на нескольких страницах, но будет случайным образом проваливаться на случайной странице с вышеупомянутым исключением.

Я уже просмотрел многочисленные сообщения Stackru со схожими проблемами и попробовал некоторые из предложенных исправлений, таких как использование класса WebDriverWait для реализации явного ожидания, использование блоков try/ исключением для зацикливания и повторного определения элемента с помощью driver.find_element... метод при условии возникновения исключения StaleElementReferenceException и при попытке

driver.find_element_by_id

а также

driver.find_element_by_xpath.

Ниже мой код:

url = "http://www.grownjkids.gov/ParentsFamilies/ProviderSearch"
driver = webdriver.Chrome('MY WEBDRIVER FILE PATH')
driver.implicitly_wait(10)

driver.get(url)

#clears text box 
driver.find_element_by_class_name("form-control").clear()

#clicks on search button without putting in any parameters, getting all the results
search_button = driver.find_element_by_id("searchButton")
search_button.click()

#function to find next button 
def find(driver):
    try:
        element = driver.find_element_by_class_name("next")
        if element: 
            return element
    except StaleElementReferenceException:
            while (attempts < 100):
                element = driver.find_element_by_class_name("next")
                if element: 
                    return element
                attempts += 1

#keeps on clicking next button to fetch each group of 5 results 
while True: 
    try: 
        nextButton = WebDriverWait(driver, 2000).until(find)
    except NoSuchElementException:
        break
    nextButton.send_keys('\n') 
    table = driver.find_element_by_id("results")
    html_source = table.get_attribute('innerHTML')
    print html_source

У меня есть предчувствие увеличить WebDriverWait до 2000, и зацикливание 100 попыток не работает (возможно, оно не входит в этот блок?), Потому что результаты одинаковы, независимо от того, насколько я их увеличу. Любые отзывы о моем коде также приветствуются, так как я впервые использую Selenium, и я довольно плохо знаком с Python.

2 ответа

Решение

StaleElementReferenceException возникает, когда веб-драйвер пытается выполнить действие с элементом, который больше не существует или недействителен.

Я добавил свободное ожидание в ваш код, чтобы элемент был доступен для нажатия, попробуйте следующий код:

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import StaleElementReferenceException, WebDriverException, NoSuchElementException
from selenium.webdriver.common.by import By

driver= webdriver.Chrome('C:\NotBackedUp\chromedriver.exe')
url = "http://www.grownjkids.gov/ParentsFamilies/ProviderSearch"
driver.get(url)

#clears text box 
driver.find_element_by_class_name("form-control").clear()

#clicks on search button without putting in any parameters, getting all the results
search_button = driver.find_element_by_id("searchButton")
search_button.click()

#keeps on clicking next button to fetch each group of 5 results 
i=1
while True:
    wait = WebDriverWait(driver, timeout=1000, poll_frequency=1, ignored_exceptions=[StaleElementReferenceException, WebDriverException]);
    try:
        element = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'next')))
        element.click()
        print("Clicked ===> ", i)
        i+=1
    except NoSuchElementException:
            break

    table = driver.find_element_by_id("results")
    html_source = table.get_attribute('innerHTML')
    print html_source

Беглое ожидание попытается нажать на следующий символ, игнорируя исключения StaleElementReferenceException и WebDriverException.

И цикл прервется, когда вы получите исключение NoSuchElementException.

Я надеюсь, что это помогает...

StaleElementReferenceException обычно возникает, когда вы пытаетесь взаимодействовать с элементом, а не когда вы его изначально находите.

Оберните ваше взаимодействие с элементом в Try Except, который вместо этого перехватывает StaleElementReferenceException.