I am trying to get the inner text of a specific element on a website (which runs on React production build) using Selenium. I am doing the following:
driver = webdriver.Firefox()
driver.get('some site using React')
WebDriverWait(driver, 10).until(
expected_conditions.text_to_be_present_in_element(
(By.CSS_SELECTOR, '.parent p'),
'some text here'
)
)
This all works - in fact, I can even access the element afterwards:
elem = driver.find_element(By.CSS_SELECTOR, '.parent p')
print(elem)
# -> <selenium.webdriver.firefox.webelement.FirefoxWebElement (session="57b82b73-0c6a-40c5-97e1-b5861b3d43e6", element="736edc49-cef0-4723-b69e-afabd80f1e9d")>
However, as soon as I try to do anything with this, I get a StaleElementReferenceException. For instance,
print(elem.get_attribute('innerText'))
or
print(elem.text)
both throw the following error:
selenium.common.exceptions.StaleElementReferenceException: Message: The element reference of <p> is stale; either the element is no longer attached to the DOM, it is not in the current frame context, or the document has been refreshed
I have also tried replacing expected_conditions.text_to_be_present_in_element
with expected_conditions.presence_of_element_located
, but the issue still persists. I am at a loss for why I am able to successfully await the element's loading, even recognising that the text in said element matches my format (i.e. we are able to read the text, somehow), and even being able to print the element itself - but when I attempt to get its text, even just read a property (not call a method), I get this exception. Sometimes, on perhaps every third attempt or so, it works - but then it goes back to not working again.
How can I get around this error, in order to access my text as soon as it matches my intended format (i.e. includes 'some text here')?
As per @PDHide's request, here is my full code:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium import webdriver
driver = webdriver.Firefox()
while True: # Running repeatedly, to ensure that the solution works consistently over multiple executions
driver.get('url')
WebDriverWait(driver, 10).until(
EC.text_to_be_present_in_element(
(By.CSS_SELECTOR, '.parent p'),
'some text here'
)
)
print(driver.find_element(By.CSS_SELECTOR, '.parent p').get_attribute('innerText'))
This usually works for one or two executions, before breaking and reverting to throwing a StaleElementReferenceException
.