Je reçois le message d'erreur suivant lors de l'utilisation de Selenium en python:
Selenium.common.exceptions.StaleElementReferenceException: Message: u'stale element reference: element is not attached to the page document\n
Il est intéressant de noter que l'erreur apparaît à différents moments de la boucle for. Parfois, cela passe par exemple. 4 itérations et autres fois, par exemple. 7.
Certains des codes pertinents en cours d'exécution sont les suivants:
for i in range(0, 22):
u = driver.find_elements_by_id("data")
text = u[0].get_attribute("innerHTML")
driver.find_elements_by_class_name("aclassname")[0].click()
Qu'est-ce que cette erreur signifie et qu'est-ce que je peux essayer de résoudre?
Prise en charge du sélénium Explicit
et Implicit
Attend. Si vous pensez qu’attendre un certain temps est suffisant pour que votre page soit chargée, utilisez:
driver.implicitly_wait(secs)
mais si vous voulez attendre un événement spécial (par exemple, attendre qu'un élément particulier soit chargé), vous pouvez faire quelque chose comme:
from Selenium.webdriver.support.ui import WebDriverWait
...
...
def find(driver):
element = driver.find_elements_by_id("data")
if element:
return element
else:
return False
element = WebDriverWait(driver, secs).until(find)
Cela signifie que l'élément n'est plus dans le DOM ou qu'il a changé.
Vous êtes dans une boucle. Pensez à ce qui se passe pendant les itérations:
Le code suivant peut vous aider à trouver l'élément:
from Selenium.common.exceptions import NoSuchElementException
from Selenium.common.exceptions import StaleElementReferenceException
from Selenium.webdriver.common.by import By
from Selenium.webdriver.support.ui import WebDriverWait
from Selenium.webdriver.support import expected_conditions
ignored_exceptions=(NoSuchElementException,StaleElementReferenceException,)
your_element = WebDriverWait(your_driver, some_timeout,ignored_exceptions=ignored_exceptions)\
.until(expected_conditions.presence_of_element_located((By.ID, Your_ID)))
Lorsque la page Web a été rafraîchie ou est passée d'une fenêtre ou d'un formulaire différent à une autre et que vous tentez d'accéder à un élément, l'utilisateur obtiendra l'exception.
Utilisez webdriverwait dans le bloc try --except avec la boucle for: EX:
driver.find_element_by_id(tc.value).click()
Réparer :
from Selenium.webdriver.common.by import By
from Selenium.webdriver.support.ui import WebDriverWait
from Selenium.webdriver.support import expected_conditions as EC
driver.find_element_by_id(tc.value).click()
for i in range(4):
try:
run_test = WebDriverWait(driver, 120).until( \
EC.presence_of_element_located((By.XPATH, "xpath")))
run_test.click()
break
except StaleElementReferenceException as e:
raise e
>>>Stale Exceptions can be handled using **StaleElementReferenceException** to continue to execute the for loop.
from Selenium.common import exceptions
# and customize your code of for loop as:
for i in range(0, 22):
try:
u = driver.find_elements_by_id("data")
text = u[0].get_attribute("innerHTML")
driver.find_elements_by_class_name("aclassname")[0].click()
except exceptions.StaleElementReferenceException:
pass
Voici la solution python à ce problème:
def clickAndCatchStaleRefException(locator):
driver = sel2._current_browser()
result = False
attempts = 0
locator = locator[6:]
# This line is optional because sometimes you pass a xpath from a varibles file
# that starts with 'xpath='. This should be omitted otherwise the find_element_by_xpath
# function will throw an error.
# But if you pass an xpath directly you don't need this
while attempts < 2:
try:
driver.find_element_by_xpath(locator).click()
result = True
break
except EC as e:
raise e
finally:
attempts += 1
return result