'Selenium stale element

i just start with selenium and have problems with webscraping from a betting website that keeps updating it's data. Because elements keeps updating i get sometimes stale element. I think this is because the elements are no longer attached to the DOM, but i don't now how i can't avoid this. How can I fix my code to handle the issue and then figure out a solution to it instead of re running the code?

Here is the code i have:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time


options = Options()
options.headless = True
website = 'https://www.betcity.nl/sportsbook#event/1007785387'
s = Service('C:/chromedriver.exe')

options.add_argument('window-size=1920x1080')
driver = webdriver.Chrome(service=s, options=options)
driver.get(website)
time.sleep(10)
box = driver.find_element(By.CLASS_NAME, 'KambiBC-scroller-wrapper')
rows = WebDriverWait(box, 50).until(EC.presence_of_all_elements_located((By.XPATH, "//ul[contains(@class, 'KambiBC-betoffer-categories-filter')]//a[contains(text(), 'Doelpuntenmaker')]")))
rows[0].click()

time.sleep(10)
scorer1 = []
boxs = driver.find_elements(By.CLASS_NAME, 'KambiBC-outcomes-list__column')
for box in boxs:
    rows = box.find_elements(By.XPATH, ".//h4[contains(@class, 'KambiBC-outcomes-list__row-header KambiBC-outcomes-list__row-header--participant')]//span")
    for n, odd in enumerate(rows):
        scorer1.append(odd.text)


Solution 1:[1]

After years of getting annoyed by stale element exceptions I gave up fighting with them and now just have resilient functions (or c# extension methods) that I pass my element locators to and they retry the operation for a specified time until it works.

It isn't very sophisticated but it saves a lot of pain.

c# example:

public static void WaitClickElement(this IWebDriver driver, By by, int millis = 2000)
    {
        TestTimer timer = new TestTimer(millis);

        while(!timer.Expired())
        {
            try
            {
                driver.FindElement(by).Click();
                break;
            }
            catch(Exception e)
            {
                if(timer.Expired()) {
                    throw new Exception("Could not click element in specified time: " + by.ToString() + "\n" + e.Message);
                }
            }
        }
        
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 MonkeyTester