Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

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

python - Element goes stale on click

I am opening a new page with every click and downloading a video from that page. It works for the first page, but when the second link is clicked in the for loop(link clicks open a new tab), the Download button goes stale when the Download button is clicked, but not on the first iteration, only on the subsequent ones, if I choose to pass this exception.

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.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import Select
import os
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_extension('1.5_0.crx') #This was not the issue. So, not needed.
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('USER')
password = driver.find_element_by_xpath('//*[@id="password"]')
password.send_keys('PASS') 
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, 80).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_xpath('/html/body/div[2]/div[2]/div/div/div/div[3]/div[2]/div[1]/div/div[3]/div[3]/vm-match-actions/div/div/div[1]/div[2]/a')
                driver.execute_script("arguments[0].scrollIntoView();", link)
                actionChains.context_click(link).perform()
                pyautogui.typewrite(['down', 'down', 'down', 'down', 'enter'])
                time.sleep(5)
                pyautogui.hotkey('enter')
                driver.refresh()
                WebDriverWait(driver, 80).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)

This error suggests the element was found that is why it is inside the if loop, but goes stale on click?

  Traceback (most recent call last):
  File "C:/Users/user/PycharmProjects/Freelance/stack.py", line 59, in <module>
    actionChains.context_click(link).perform()
  File "C:UsersuserPycharmProjectsFreelancevenvlibsite-packagesseleniumwebdrivercommonaction_chains.py", line 80, in perform
    self.w3c_actions.perform()
  File "C:UsersuserPycharmProjectsFreelancevenvlibsite-packagesseleniumwebdrivercommonactionsaction_builder.py", line 76, in perform
    self.driver.execute(Command.W3C_ACTIONS, enc)
  File "C:UsersuserPycharmProjectsFreelancevenvlibsite-packagesseleniumwebdriver
emotewebdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:UsersuserPycharmProjectsFreelancevenvlibsite-packagesseleniumwebdriver
emoteerrorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
  (Session info: chrome=87.0.4280.141)

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

1 Reply

0 votes
by (71.8m points)

Using and API you can get all data, video urls and download videos.

Code below collect video urls. To download videos you can also use , find details here: how to download file using requests

import requests

user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_0) AppleWebKit/537.36 (KHTML, like Gecko) ' 
             'Chrome/87.0.4280.141 Safari/537.36'

with requests.Session() as session:
    session.headers = {
        'Connection': 'keep-alive',
        'Accept': 'application/json, text/plain, */*',
        'X-Requested-With': 'XMLHttpRequest',
        'Authorization': 'Basic cG9ydGFsOg==',
        'User-Agent': user_agent,
        'Content-Type': 'application/x-www-form-urlencoded',
        'Origin': 'https://portal.volleymetrics.hudl.com',
        'Sec-Fetch-Site': 'same-site',
        'Sec-Fetch-Mode': 'cors',
        'Sec-Fetch-Dest': 'empty',
        'Referer': 'https://portal.volleymetrics.hudl.com/',
        'Accept-Language': 'en-US,en;q=0.9',
    }

    data = {
        'grant_type': 'password',
        'username': 'merin_sinha24',
        'password': '12345678'
    }
    response = session.post('https://api.volleymetrics.hudl.com/acct/oauth/token', data=data)
    token = response.json()['access_token']
    session.headers.update({'Authorization': 'Bearer ' + token})

    match_videos = dict()
    page = 1
    while True:
        params = (
            ('page', page),
            ('size', '20'),
            ('sort', ['matchDate,desc', 'id,desc']),
            ('startDate', '2019-10-01T00:00:00.000'),
            ('endDate', '2021-01-15T09:48:47.310'),
            ('matchType', 'match'),
        )
        response = session.get('https://api.volleymetrics.hudl.com/portal/events/other', params=params)
        matches = response.json()['content']

        for match in matches:
            r = session.get(f'https://api.volleymetrics.hudl.com/analysis/matches/{match["id"]}')
            video_url = r.json()['encodedVideoUrl']
            if video_url is not None:
                file_name = video_url.split('/')[-1]
                match_videos[file_name] = video_url
            else:
                print("no video url")

        if page == int(response.json()['totalPages']):
            break
        page += 1

You will get:

{
  "2021.01.14-01.59-186589.mp4": "http://vm-transcoded-videos.s3.amazonaws.com/2021.01.14-01.59-186589.mp4",
  "2021.01.13-09.49-178458.mp4": "http://vm-transcoded-videos.s3.amazonaws.com/2021.01.13-09.49-178458.mp4",
  "2021.01.11-15.11-178456.mp4": "http://vm-transcoded-videos.s3.amazonaws.com/2021.01.11-15.11-178456.mp4",
  "2021.01.08-09.44-184883.mp4": "http://vm-transcoded-videos.s3.amazonaws.com/2021.01.08-09.44-184883.mp4",
  "2020.11.20-19.43-179457.mp4": "http://vm-transcoded-videos.s3.amazonaws.com/2020.11.20-19.43-179457.mp4",
  "2020.11.11-01.26-178151.mp4": "http://vm-transcoded-videos.s3.amazonaws.com/2020.11.11-01.26-178151.mp4",
  "2020.11.11-01.45-178117.mp4": "http://vm-transcoded-videos.s3.amazonaws.com/2020.11.11-01.45-178117.mp4",
  "2020.11.10-10.48-177923.mp4": "http://vm-transcoded-videos.s3.amazonaws.com/2020.11.10-10.48-177923.mp4",
  "2020.11.06-18.50-176707.mp4": "http://vm-transcoded-videos.s3.amazonaws.com/2020.11.06-18.50-176707.mp4",
  "2020.12.28-13.54-177032.mp4": "http://vm-transcoded-videos.s3.amazonaws.com/2020.12.28-13.54-177032.mp4",
  "2020.10.29-23.46-175761.mp4": "http://vm-transcoded-videos.s3.amazonaws.com/2020.10.29-23.46-175761.mp4",
  "2020.10.28-19.01-175566.mp4": "http://vm-transcoded-videos.s3.amazonaws.com/2020.10.28-19.01-175566.mp4",
  "2020.10.23-19.27-174548.mp4": "http://vm-transcoded-videos.s3.amazonaws.com/2020.10.23-19.27-174548.mp4",
  "2020.10.16-18.39-172318.mp4": "http://vm-transcoded-videos.s3.amazonaws.com/2020.10.16-18.39-172318.mp4",
  "2020.10.15-19.04-172317.mp4": "http://vm-transcoded-videos.s3.amazonaws.com/2020.10.15-19.04-172317.mp4",
  "2020.10.15-12.43-172783.mp4": "http://vm-transcoded-videos.s3.amazonaws.com/2020.10.15-12.43-172783.mp4",
  "2020.10.14-19.02-172316.mp4": "http://vm-transcoded-videos.s3.amazonaws.com/2020.10.14-19.02-172316.mp4",
  "2020.10.14-11.04-172417.mp4": "http://vm-transcoded-videos.s3.amazonaws.com/2020.10.14-11.04-172417.mp4"
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...