Не удается исправить 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.