I am working to collect emails addresses from some schools for a survey. I leveraged several sources and put together this code. The code overall is good, however I started getting this error: StaleElementReferenceException.
Here is my code:
# imports
from seleniumwire import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Driver & url
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
url = "https://www.aes.k12.nj.us/domain/159"
driver.get(url)
contacts = []
# Function to extract contacts within the car`your text`ds
def extract_contacts():
contact_cards = driver.find_elements( By.CSS_SELECTOR, 'div[class="staff"]')
print(f"Total contacts in the current page is : {len(contact_cards)}")
new_contact = {}
for contact in contact_cards:
new_contact = {}
staffName = contact.find_element(
By.CLASS_NAME,"staffname").text
staffJob = contact.find_element(
By.CLASS_NAME,"staffjob").text
staffDepartment = contact.find_element(
By.CLASS_NAME,`your text` "staffdepartment").text
staffRoom = contact.find_element(
By.CLASS_NAME, "staffroom").text
staffEmail = contact.find_element(
By.CLASS_NAME, "staffemail").text
new_contact['staffName'] = staffName
new_contact['staffJob'] = staffJob
new_contact['staffDepartment'] = staffDepartment
new_contact['staffRoom'] = staffRoom
new_contact['staffEmail'] = staffEmail
contacts.append(new_contact)
return contacts
# Run the code
contacts = []
total_pages = int(driver.find_element(
By.CSS_SELECTOR, 'div[id="ui-paging-container"] li:last-child').text)
print(f"Total pages: {total_pages}")
for current_page in range(total_pages):
print("We are working on page..", current_page + 1)
del driver.requests
extract_contacts()
next_page_btn = driver.find_element(
By.XPATH, f'//*[@id="ui-paging-container"]/ul/li[{current_page+1}]')
WebDriverWait(driver,15).until(EC.element_to_be_clickable((By.XPATH,f'//*[@id="ui-paging-container"]/ul/li[{current_page+1}]'))).click()
next_page_btn.click()
total = len(contacts)
print(f"We're done....There were {total} contacts")
print(contacts)
End of my code.
Here is the output & the error message:
Total pages: 4 We are working on page.. 1 Total contacts in the current page is : 20 We are working on page.. 2 Total contacts in the current page is : 20 We are working on page.. 3 Total contacts in the current page is : 20
type here
StaleElementReferenceException Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_8076\1456281270.py in <module>
8 print("We are working on page..", current_page + 1)
9 del driver.requests
---> 10 extract_contacts()
11
12 next_page_btn = driver.find_element(
~\AppData\Local\Temp\ipykernel_8076\854479575.py in extract_contacts()
9 new_contact = {}
10
---> 11 staffName = contact.find_element(
12 By.CLASS_NAME,"staffname").text
13 staffJob = contact.find_element(
C:\ProgramData\Anaconda3\lib\site-packages\selenium\webdriver\remote\webelement.py in text(self)
87 def text(self) -> str:
88 """The text of the element."""
---> 89 return self._execute(Command.GET_ELEMENT_TEXT)["value"]
90
91 def click(self) -> None:
C:\ProgramData\Anaconda3\lib\site-packages\selenium\webdriver\remote\webelement.py in _execute(self, command, params)
408 params = {}
409 params["id"] = self._id
--> 410 return self._parent.execute(command, params)
411
412 def find_element(self, by=By.ID, value=None) -> WebElement:
C:\ProgramData\Anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py in execute(self, driver_command, params)
442 response = self.command_executor.execute(driver_command, params)
443 if response:
--> 444 self.error_handler.check_response(response)
445 response["value"] = self._unwrap_value(response.get("value", None))
446 return response
C:\ProgramData\Anaconda3\lib\site-packages\selenium\webdriver\remote\errorhandler.py in check_response(self, response)
247 alert_text = value["alert"].get("text")
248 raise exception_class(message, screen, stacktrace, alert_text) # type: ignore[call-arg] # mypy is not smart enough here
--> 249 raise exception_class(message, screen, stacktrace)
StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
(Session info: chrome=109.0.5414.75)
Stacktrace:
Backtrace:
(No symbol) [0x00526643]
(No symbol) [0x004BBE21]
(No symbol) [0x003BDA9D]
(No symbol) [0x003C09E4]
(No symbol) [0x003C08AD]
(No symbol) [0x003C0B30]
(No symbol) [0x003EC7C0]
(No symbol) [0x0040FD7C]
(No symbol) [0x003E641F]
(No symbol) [0x004100D4]
(No symbol) [0x00426B09]
(No symbol) [0x0040FB76]
(No symbol) [0x003E49C1]
(No symbol) [0x003E5E5D]
GetHandleVerifier [0x0079A142+2497106]
GetHandleVerifier [0x007C85D3+2686691]
GetHandleVerifier [0x007CBB9C+2700460]
GetHandleVerifier [0x005D3B10+635936]
(No symbol) [0x004C4A1F]
(No symbol) [0x004CA418]
(No symbol) [0x004CA505]
(No symbol) [0x004D508B]
BaseThreadInitThunk [0x778800F9+25]
RtlGetAppContainerNamedObjectPath [0x77E57BBE+286]
RtlGetAppContainerNamedObjectPath [0x77E57B8E+238]
I tried adding some workarounds assuming dynamic elements are present in the website, but that did not work neither.
staffName = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((
By.CLASS_NAME,"staffname"))).text