Как предотвратить исключение StaleElementReferenceException при нажатии на каждый элемент в списке лиг с помощью Selenium через Python

#python #selenium-webdriver #web-scraping #webdriverwait #staleelementreferenceexception

#python #selenium-webdriver #очистка веб-страниц #webdriverwait #исключение staleelementreferenceexception

Вопрос:

Работа на этом веб-сайте: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
  

Код выбирает первую лигу из списка, затем щелкает значок футбола, чтобы вернуться на главную страницу. При попытке щелкнуть вторую лигу из списка, исключение StaleElementReferenceException возникает из-за обновления страницы. Как это можно предотвратить?

Редактировать:

Мне действительно нужно решение, чтобы не потерять веб-элемент во время цикла for. Этот футбольный веб-сайт предназначен только для вас, ребята, чтобы проверить мою проблему в действии.

Комментарии:

1. Вам не нужно нажимать на футбольный мяч. Лиги все еще присутствуют даже после того, как вы нажмете на одну. Что вы могли бы сделать, что немного грубо, получить текст элемента, поэтому на британском сайте я выбрал «чемпионат». Затем, когда я завершу задачи на этой странице, я хочу нажать на первую лигу, чтобы снова найти ссылки на панели навигации слева, найти текст ссылки, который соответствует предыдущему, затем вы могли бы создать переменную с номером индекса элемента, затем вы можете найти все и выбрать индекс элемента плюс один

2. Немного отредактировал основной пост. Да, мне не нужно было бы нажимать значок футбола, это просто для обновления веб-страницы, поэтому может произойти потеря веб-элемента.

3. Вы понимаете, что такое StaleElementReferenceException и почему это происходит?

Ответ №1:

Почему бы просто не захватить ссылки для лиг, а затем get их. Вы можете пропустить первую ссылку, если она текущая с 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
  

Ответ №2:

Для просмотра и просмотра каждой лиги от Лиги списка вы можете открытия каждой лиги в adjusant вкладку и перейдите на вкладку выполнить необходимые действия и в конце закройте вкладку и вернитесь в Главное окно, и вы можете использовать следующее решение:

  • Блок кода:

     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:UtilityBrowserDriverschromedriver.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()