selenium编写自动化学习脚本时碰到的循环跳出问题

selenium编写自动化学习脚本时碰到的循环跳出问题

course_learn()函数for循环执行完movie_learn()后没有继续for循环,而是直接跳出了去执行course_learn()的父函数了

脚本主体函数主要是5个

1.进入课程库

 # 进入课件库
def enter_courses_library(driver):
    global library_window, course_window, movie_window
    global course_mark
    course_mark = get_recent_coursemark(driver)
    driver.find_element(By.CSS_SELECTOR,'a[href="/pc/course/courselist.do"]').click()
    time.sleep(3)
    library_window = driver.current_window_handle
    while course_mark < PASS_SCORE:
        coursestype_select(driver, course_type)
        coursestype_select(driver, '选修')

2.必修课和选修课的选择

# 判断是学习选修课还是必修课
def coursestype_select(driver,course_type):
    try:
    # 等待元素出现,并定位到元素 这里detail是整个页面的ID
        WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="detail"]/div[2]/div[1]/div/button[2]')))
        driver.find_element(By.XPATH, '//*[@id="detail"]/div[2]/div[1]/div/button[2]').click()
    except:
    # 如果出现异常,则打印错误消息
        print("无法定位到|列表显示|,请检查定位是否正确")
    # 点击必修函数
    driver.find_element(By.CSS_SELECTOR,f'a[title="{course_type}"]').click()
    time.sleep(3)
    WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH,'//*[@id="detail"]/div[2]/div[2]/div/table/tbody/tr[7]/td[2]')))
    if course_type == '必修':
        required_courses = driver.find_elements(By.XPATH, '//table/tbody/tr')
        for course in required_courses:
            course_chose(driver, course)
    else:
        optional_courses = driver.find_elements(By.XPATH, '//table/tbody/tr')
        print(len(optional_courses))
        for course in optional_courses:
            course_chose(driver, course)

3.课程选择函数

def course_chose(driver, course):
    global library_window, course_window, movie_window
    global course_mark
    try:
        img_exist = course.find_element(By.XPATH, './td[1]/img')
    except Exception as e:
        img_exist = []
    WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH,'/html/body/div[4]/div[2]/div[2]/div/table/tbody/tr[6]/td[1]/a/span')))
    if not img_exist or img_exist.get_attribute('src') != COURSE_YWC:
        course_score = course.find_element(By.XPATH, 'td[4]').text
        #将当前课程的学分进行正则去掉中文保留数字
        course_score = float(re.search(r'\d+\.?\d*', course_score).group())
        print(course_score)
        play_btn = course.find_element(By.XPATH,'./td[6]/a[@class="learn"]')
        course_url = play_btn.get_attribute('href')
        play_btn.click()
        time.sleep(3)
        WebDriverWait(driver,10).until(EC.new_window_is_opened)
        handles = driver.window_handles
        if len(handles) == 2:
            driver.switch_to.window(handles[-1])
            course_window = driver.current_window_handle
            print(driver.current_url,driver.title)
            WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH,'//*[@id="chapter"]/table/tbody/tr[1]/td[1]/span')))
            # 课程学习函数
            course_learn(driver)
            course_mark += course_score
            print("这是完整学完一个课程后,打印下当前的已经获得的couse_mark和当前课程的分数",course_mark,course_score)
            driver.close()
            time.sleep(1)
            WebDriverWait(driver,10).until(EC.number_of_windows_to_be(1))
            driver.switch_to.window(library_window)
            time.sleep(1)
            #对当前页面进行刷新,使得进度等于100%
            # driver.refresh()
            WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.XPATH, '//table/tbody/tr')))
            time.sleep(1)
            # 测试一下跳转的对不对
            main_url = driver.current_url
            print("测试能否回到课程库,当前网页的地址是: ",main_url)

4.课程学习函数

def course_learn(driver):
    global library_window, course_window, movie_window
    global waiting_time
    WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.XPATH,'//table/tbody/tr')))
    trs = driver.find_elements(By.XPATH,'//table/tbody/tr')
    for i, tr in enumerate(trs):
        print(f"当前执行循环:{i}")
        course_progress = int(tr.find_element(By.XPATH,'./td[4]/span').text)
        if course_progress != 100:
            course_times = float(tr.find_element(By.XPATH,'./td[2]/span').text)*60
            waiting_time = int(course_times * ((100-float(course_progress)) / 100))
            try:     
                tr.find_element(By.CLASS_NAME,'playBtn').click()
                WebDriverWait(driver,10).until(EC.new_window_is_opened)
                WebDriverWait(driver,10).until(EC.number_of_windows_to_be(3))
                handles = driver.window_handles
                driver.switch_to.window(handles[-1])
                movie_window = driver.current_window_handle
                movie_learn(driver)
                print(f"学完第{i}节课后的课程URL:", driver.current_url)
            except Exception as e:
                logging.exception(f"学习第{i}节课出错,异常信息:{e}")
        else:
            print(f"第{i}课已学完")      
    time.sleep(2)
    url_now = driver.current_url
    print("这是学完一个课程后,关闭当前课程回到课程库的测试",url_now)

5.视频播放函数

# 视频播放函数
def movie_learn(driver):
    global library_window, course_window, movie_window
    global waiting_time
    WebDriverWait(driver,10).until(EC.presence_of_element_located((By.CLASS_NAME,'col-md-10')))
    driver.switch_to.frame(driver.find_element(By.ID,'mainFrame'))
    first_confirm(driver)
    print(f"视频时长为{waiting_time/60}分钟")
    # 测试 改下时间
    time.sleep(5)
    # time.sleep(waiting_time + 20)
    driver.switch_to.default_content()
    driver.find_element(By.ID, 'completebtn').click()
    WebDriverWait(driver,10).until(EC.alert_is_present())
    #再次对弹出框进行确认
    driver.switch_to.alert.accept()
    # 等待视频播放函数完成一个课程学习后,跳转句柄到课程页面
    WebDriverWait(driver,10).until(EC.number_of_windows_to_be(2))
    driver.switch_to.window(course_window)
    time.sleep(2)
    driver.refresh()
    # handles = driver.window_handles
    # driver.switch_to.window(handles[1])
    print("movie_learn后面跳转窗口网页地址是否正确",driver.current_url)

selenium编写自动化学习脚本时碰到的循环跳出问题,应该就是你的程序的问题,在course_learn函数的for循环中解析到的trs可能只有一个值,所以循环了一次就退出了,你可以在这个地方把str打印输出下。
其次 跳出循环的还有一个可能就是你的程序报错了,我看你的程序捕获了异常并把异常信息写入了日志,建议查看下日志文件中的错误信息,或者修改代码使用print方法来输出错误信息,这样就可以在控制台看到报了什么错误。
如果你还不确定哪里的问题,可以使用debug调试模式一步步调试代码

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^