I am trying to go on a website, click on an element, extract the information I need from the subpage, then go back, click on the next element, extract the information I need, ...
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
url = '...'
driver = webdriver.Firefox()
driver.get(url)
elements = driver.find_elements_by_css_selector(
'.foo.cat-dog.bar')
for element in elements
link = element.find_elements(By.TAG_NAME, 'a')[0]
driver.execute_script("arguments[0].click();", link)
# extract information I need
driver.back()
time.sleep(10)
This gives me
selenium.common.exceptions.StaleElementReferenceException: Message: The element reference of [object String] "{"element-6066-11e4-a52e-4f735466cecf":"68401746-c4a4-4eac-936b-2e5a3395bc41"}" 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 Stacktrace: WebDriverError@chrome://remote/content/shared/webdriver/Errors.jsm:183:5 StaleElementReferenceError@chrome://remote/content/shared/webdriver/Errors.jsm:464:5 element.resolveElement@chrome://remote/content/marionette/element.js:681:11 evaluate.fromJSON@chrome://remote/content/marionette/evaluate.js:254:26 evaluate.fromJSON@chrome://remote/content/marionette/evaluate.js:262:29 evaluate.fromJSON@chrome://remote/content/marionette/evaluate.js:262:29 receiveMessage@chrome://remote/content/marionette/actors/MarionetteCommandsChild.jsm:79:29
Why is that? How to overcome it?
CodePudding user response:
Once you do driver.back()
it will redirect you to the previous page. Now here all the elements have become stale in nature.
You should redefine them again to get rid off of the stale element exception.
Code:
elements = driver.find_elements_by_css_selector('.foo.cat-dog.bar')
i = 1
for element in range(len(elements)):
link = driver.find_element_by_xpath(f"(//*[@class='foo cat-dog bar'])[{i}]")
link = element.find_elements(By.TAG_NAME, 'a')[0]
driver.execute_script("arguments[0].click();", link)
# extract information I need
driver.back()
i = i 1
time.sleep(10)