1

Operating on this website: https://www.livetulokset.com/

my_leagues = browser.find_element_by_id('my-leagues-list') # single element
leagues = my_leagues.find_elements_by_tag_name('li') # list of elements
for i in leagues:
    i.click()   # Click first league
    sleep(1)    # sleep second to be able to see the click in monitor
    browser.find_element_by_css_selector('a.menuTop__item:nth-child(1) > div:nth-child(2)').click() # click football icon

Code clicks first league from the list, then clicks the football icon to get back to main page. When trying to click the second league from the list, StaleElementReferenceException occurs due the page refresh. How could this be prevented?

Edit:

I really need solution for not to lose the web element during for loop. This football website is just for you guys to test my problem in action.

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
Sane90
  • 23
  • 5
  • You don't need to click the football. The leagues are still present even after you click one. What you could do which is a bit crude, get the text of the element, so on the British site I chose "championship". Then when I've completed the tasks on that page I want to click league one so I find the links on the navbar on the left again, find the link text that matches the previous one, then you could make a variable with the index number of the element, then you can find all and select the index of the element plus one – Swift Mar 08 '19 at 19:12
  • Edited main post a bit. Yes, I would not need to click the football icon, it is just for the web page to be refreshed so losing the web element can occur. – Sane90 Mar 08 '19 at 19:17
  • Do you understand what a `StaleElementReferenceException` is and why it occurs? – JeffC Mar 08 '19 at 22:11

2 Answers2

1

Why not just grab the links for the leagues and then get them. You may skip the first link if it is the current with links[1:]

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
url = 'https://www.livetulokset.com/'
driver = webdriver.Chrome()
driver.get(url)
links = [link.get_attribute('href') for link in WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "#my-leagues-list a")))]
print(links)
for item in links:
    driver.get(link)
    # do something
QHarr
  • 83,427
  • 12
  • 54
  • 101
0

To browse and view each league from the league list you can open each league in the adjusant TAB and switch to the tab to perform the necessary action and at the end close the TAB and switch back to the main window and you can use the following solution:

  • Code Block:

    from selenium import webdriver
    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 = webdriver.ChromeOptions()
    options.add_argument("start-maximized")
    options.add_argument("--disable-extensions")
    options.add_argument('disable-infobars') 
    driver = webdriver.Chrome(chrome_options=options, executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
    driver.get("https://www.livetulokset.com/")
    handel_initially  = driver.current_window_handle
    my_hrefs = [my_leagues.get_attribute("href") for my_leagues in WebDriverWait(driver,10).until(EC.visibility_of_all_elements_located((By.XPATH, "//ul[@id='my-leagues-list']/li//a")))]
    for href in my_hrefs:
        driver.execute_script("window.open('" + href +"');")
        WebDriverWait(driver, 10).until(EC.number_of_windows_to_be(2))
        handels_now =driver.window_handles
        driver.switch_to.window([x for x in handels_now if x != handel_initially][0])
        time.sleep(5) # perform your tasks within the new tab for each league
        driver.close()
        driver.switch_to_window(handel_initially)
    driver.quit()
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352