某在线学习平台自动挂视频

前言:

遇到一个视频学习平台,视频无法快进,学习过程中会出现习题,需要在一定时间内提交答案(不管对错),才会继续视频的学习。其间若是逾时不答题或是出现其它错误,视频播放进度都不算。

使用Python + selenium,实现自动挂视频:

  • 半自动登录。帐号密码可设定,在登录页面会自动输入,但需要自己输入验证码(这一块处理起来也不难,它的验证码还是比较好辩认),并且点击“个人登录”。
  • 自动进入课程学习。
  • 处理在视频播放时间里出现的所有情况:答题、错误提示等。
  • 播放完毕后自动进入下一个课程。
  • 全程使用一个logger装饰器,把main()包装起来,让所有的输出(包括错误)转存到logger.log文件中。
  • 最主要是在handle_interference()函数中,处理播放视频时出现的所有干扰,以便视频能顺利播放完。

代码如下 :

# -*- coding: utf-8 -*-
"""
广东省******公需课在线学习平台 自动点播
存在问题:handle_interference()中处理“网络故障”的判断条件不正确
"""
import time
import sys
import functools

from selenium import webdriver
from selenium.common import exceptions

USER_NAME = '******'
USER_PWD = '******'
now = time.strftime('[%H:%M:%S]', time.localtime())
login_url = 'http://******/zxpx/index?f=73075572383248020'  # 登录页面
classes_url = 'http://******/zxpx/hyper/courseDetail?ocid=OC201903290000005403'  # “课程详情”页面地址


def logger(func):
    """ 装饰器 将系统输出转到logger.log文件 """
    @functools.wraps(func)
    def log():
        with open('logger.log', 'a', encoding='utf-8') as log_file:
            org_err, org_out = sys.stderr, sys.stdout
            sys.stderr, sys.stdout = log_file, log_file
            func()
            sys.stderr, sys.stdout = org_err, org_out

    return log


def login(driver, url):
    """ 登录平台 """
    try:
        driver.get(url)
        time.sleep(2)
        driver.find_element_by_id('username_personal').send_keys(USER_NAME)
        driver.find_element_by_id('password_personal').send_keys(USER_PWD)
        driver.find_element_by_id('vcode_personal').click()

        # 手动填写验证码,并登录
        while True:
            time.sleep(3)
            if driver.title == '首页':
                return True, None
    except exceptions.NoSuchElementException:
        return False, '非登录页面'


def start_new_video(driver, n):
    """ 获取并开始新课视频 """
    try:
        new_class = driver.find_elements_by_xpath('//a[contains(text(), "点击学习")]')[n]
    except:
        return False, '找不到学习课程。'
    else:
        print('{} 开始新一课: {}'.format(now, new_class.get_attribute('href')))
        new_class.click()
        time.sleep(5)
        state, msg = play_video(driver)
        if state:
            return True, 'success'
        else:
            return False, msg


def play_video(driver):
    """ 点击页面中的视频object元素,开始播放 """
    if driver.title == '课件学习':
        try:
            driver.find_element_by_xpath('//object/embed').click()
        except exceptions.NoSuchElementException:
            return False, '找不到视频'
        else:
            return True, 'success'
    else:
        return False, '非课件网面'


def handle_interference(driver):
    """
    自动点击处理视频播放过程中出现的题目选择和异常告警
    :return:
        (True, 'next_class"): 正常,并视频播放完毕
        (Flase, msg):异常
    """
    print('{} 处理视频页面:答题和错误处理'.format(now))
    while driver.title == '课件学习':
        # 处理页面中出现的异常对话框:选择确定
        try:
            driver.find_element_by_xpath('//*[contains(text(), "确定")]').click()
            print('{} 选择确定'.format(now))
            time.sleep(1)
        except:
            pass

        # 选择视频过程中出现题目的正确答案
        try:
            driver.find_element_by_xpath('//div[@id="aadiv"]/input').click()
            print('{} 选择正确'.format(now))
            time.sleep(1)
        except:
            pass

        # 提交答案
        try:
            driver.find_element_by_class_name('reply-sub').click()
            print('{} 选择提交'.format(now))
            time.sleep(1)
        except:
            pass

        # 若出现告警对话框时选择确定通过
        try:
            driver.switch_to.alert.accept()
            print('{} 对话框确定'.format(now))
            time.sleep(1)
        except:
            pass

        # 视频播放的进度(正常情况下以**%的形式出现,异常则说明视频播放完毕)
        try:
            driver.find_element_by_id('realPlayVideoTime')
        except exceptions.NoSuchElementException:
            return True, 'next_class'

        # 处理网络故障提示
        try:
            driver.find_element_by_xpath('//*[contains(text(), ‘网络故障,请刷新’)]')  # 网络故障这个提示有点问题,待修复
            driver.find_element_by_xpath('//*[contains(text(), "确定")]').click()
        except:
            pass
        else:
            driver.refresh()
            print('{} 刷新页面'.format(now))
            time.sleep(3)
            state, msg = play_video(driver)
            if not state:
                return False, msg

        time.sleep(5)


@logger
def main():
    with webdriver.Ie(executable_path='IEDriverServer.exe') as driver:
        logined, login_msg = login(driver, login_url)
        if logined:
            while True:
                driver.get(classes_url)
                time.sleep(2)
                new_video_state, new_video_msg = start_new_video(driver, 0)
                if new_video_state:
                    handle_state, handle_msg = handle_interference(driver)
                    if not handle_state:
                        print('{} {}'.format(now, handle_msg))
                else:
                    print('{} {}'.format(now, new_video_msg))
                    return False
        else:
            print('{} {}'.format(now, login_msg))
            return False


if __name__ == '__main__':
    main()

猜你喜欢

转载自blog.csdn.net/qq_41090453/article/details/98871867
今日推荐