某在線學習平臺自動掛視頻

前言:

遇到一個視頻學習平臺,視頻無法快進,學習過程中會出現習題,需要在一定時間內提交答案(不管對錯),纔會繼續視頻的學習。其間若是逾時不答題或是出現其它錯誤,視頻播放進度都不算。

使用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()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章