Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
190 views
in Technique[技术] by (71.8m points)

Stale Element after downloading file selenium python

Trying to download videos after clicking a link. It works for the first page, but when the second link opens a new page, it says the element went stale while it is right-clicking it.

from selenium import webdriver
import time
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

from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver import ActionChains
import pyautogui

chrome_options = Options()
prefs = {"download.default_directory" : "C:\Users\user\Desktop\"}
chrome_options.add_experimental_option("prefs",prefs)
driver = webdriver.Chrome('C:/chromedriver.exe', options=chrome_options)
driver.get('https://portal.volleymetrics.hudl.com/#/auth/login')
actionChains = ActionChains(driver)
driver.maximize_window()
user = driver.find_element_by_xpath('//*[@id="username"]')
user.send_keys('merin_sinha24')
password = driver.find_element_by_xpath('//*[@id="password"]')
password.send_keys('password') #That is not the password
driver.find_element_by_xpath('//*[@id="login-content"]/form/button').click()
WebDriverWait(driver, 15).until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#left-menu-container > div.left-menu-button-container-top > left-menu-button:nth-child(2)'))).click()
driver.find_element_by_xpath('//*[@id="portal-matches-tabs"]/vm-tabs/div/div[2]').click()
time.sleep(9)
'''driver.find_element_by_xpath('//*[@id="portal-matches-advanced-filters-text"]').click()
time.sleep(5)
start = driver.find_element_by_xpath('//*[@id="portal-matches-advanced-filters-container"]/div/ng-transclude/div[1]/div[2]/div[1]/vm-input-box/div[2]/div/input')
start.send_keys('01102020')
end = driver.find_element_by_xpath('//*[@id="portal-matches-advanced-filters-container"]/div/ng-transclude/div[1]/div[2]/div[2]/vm-input-box/div[2]/div/input')
end.send_keys('11012021')
driver.find_element_by_xpath('//*[@id="portal-matches-advanced-filters-container"]/div/ng-transclude/div[3]/button[1]').click()'''
main_div = driver.find_elements_by_xpath('//div[@class="generic-table-two-row-group"]')
main_div = main_div[1]
links = main_div.find_elements_by_class_name('my-matches-table-row-container')
count = 0
while(len(links)!=count):
    links = main_div.find_elements_by_class_name('my-matches-table-row-container')
    link=links[count]
    count+=1
    link.click()
    parent_window = driver.current_window_handle
    all_windows = driver.window_handles
    child_window = [window for window in all_windows if window != parent_window][0]
    driver.switch_to.window(child_window)
    video = WebDriverWait(driver, 50).until(EC.visibility_of_element_located((By.ID, 'vm-match-video')))
    if not video:
        break
    else:
        div1 = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CLASS_NAME, 'vm-match-actions-directive')))
        divs2 = div1.find_elements_by_class_name('button-container')
        count2 = 0
        while(len(divs2)!=count2):
            divs2 = div1.find_elements_by_class_name('button-container')
            div=divs2[count2]
            count2 +=1
            if 'Video' and 'Download' in div.text:
                link = div.find_element_by_tag_name('a')
                actionChains.context_click(link).perform()
                pyautogui.typewrite(['down', 'down', 'down', 'down', 'enter'])
                time.sleep(5)
                pyautogui.hotkey('enter')
                driver.refresh()
                WebDriverWait(driver, 30).until(EC.visibility_of_element_located((By.ID, 'vm-match-video')))
                try:
                    driver.find_element_by_xpath('//*[@id="portal-match-controls-column"]/div[3]/vm-match-actions/div/div/div[1]/div[4]/span[2]').click()
                    driver.find_element_by_xpath('//button[contains(text(),"I Accept")]').click()
                    time.sleep(6)
                    break
                except:
                    break
            else:
                continue
    driver.close()
    driver.switch_to.window(parent_window)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
links = main_div.find_elements_by_class_name('my-matches-table-row-container')
count = 0
while(len(links)!=count):
    links = main_div.find_elements_by_class_name('my-matches-table-row-container')
    link=links[count]
    count+=1
    link.click()
    parent_window = driver.current_window_handle
    all_windows = driver.window_handles
    child_window = [window for window in all_windows if window != parent_window][0]
    driver.switch_to.window(child_window)
    time.sleep(13)
    error = driver.find_element_by_class_name('video-message')
    if error.text == 'No video to display.':
        break
    else:
        div1 = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CLASS_NAME, 'vm-match-actions-directive')))
        divs2 = div1.find_elements_by_class_name('button-container')
        count2 = 0
        while(len(divs2)!=count2):
            divs2 = div1.find_elements_by_class_name('button-container')
            div=divs[count2] 
            count2+ =1
            if 'Video' and 'Download' in div.text:
                link = div.find_element_by_tag_name('a')
                actionChains.context_click(link)
                actionChains.perform()
                pyautogui.typewrite(['down', 'down', 'down', 'down', 'enter'])
                time.sleep(5)
                pyautogui.hotkey('enter')
                driver.refresh()
                time.sleep(15)
                try:
                    driver.find_element_by_xpath('//*[@id="portal-match-controls-column"]/div[3]/vm-match-actions/div/div/div[1]/div[4]/span[2]').click()
                    driver.find_element_by_xpath('//button[contains(text(),"I Accept")]').click()
                    time.sleep(4)
                    break
                except:
                    break
            else:
                continue
    driver.close()
    driver.switch_to.window(parent_window)

             

you should always find divs again , as you are clicking 'link' and this modifies the DOM, when ever DOM ( PAge html) is modified you have find all elements again as the previous reference is lost , this is why you get stale element

you can use driver.back() to navigate back


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...