準備工作
- 找到學習通WEB端,找到新版學習通登陸頁面,默認登陸頁面有問題,這裏我們需要在url中傳入參數
newversion=true
啓動新版頁面 - 之後在幾種登陸方式中來回橫條,我們很容易發現
loginType
是url中用來指定登陸方式的,其中默認是1,手機號密碼登陸;2位手機號驗證碼登陸;3位學號密碼登陸,但是3加入的驗證碼,我們需要用到一些打碼平臺,所以自動登陸時會有一定成本,再次看來第一種手機密碼登陸爲最優登陸方式 - 使用
Selenium
庫來啓動瀏覽器,如果想要了解selenium庫可以看我之前寫的一片博客selenium庫使用方法。 - 學習通部分課程需要回答問題,解決此問題需要題庫,展示無法做出題庫功能,所以我們在這裏選擇使用一個插件自動觀看超新星網站插件這是在GitHub上開源的一個項目,可以做到結束後換級和自動答題(我寫的程序主要是用來啓動瀏覽器和進入播放頁面的。)
整體規劃
功能還不完善,等之後有空會完善一下
import time
from bs4 import BeautifulSoup
from selenium import webdriver
# 行爲鏈
from selenium.webdriver.common.action_chains import ActionChains
class AutoClassroom:
def __init__(self, user='尋覓最帥', pd='尋覓我愛你', classroom=None):
# 登陸網址傳入參數logintype的值爲:1手機號密碼登陸,2手機號驗證碼登陸,3學號密碼登陸(第三種方式有驗證碼,每次登陸需要一定成本,不建議使用)
self.login_url = 'https://passport2.chaoxing.com/login?newversion=true&loginType={}'
# 用戶名
self.login_user = user
# 登陸密碼
self.login_password = pd
# 課名
self.classroom = classroom
# 瀏覽器對象
self.driver = None
def start_web(self):
"""啓動瀏覽器"""
# 我的電腦上用的是火狐瀏覽器與其配套的插件
# 先加載火狐的插件
config = webdriver.FirefoxProfile(r"C:\Users\fan45\AppData\Roaming\Mozilla\Firefox\Profiles\pfv6rlbm.default-release")
self.driver = webdriver.Firefox(config)
# self.driver.set_window_position(400, 3)
# 學習通服務器不好,隱式睡眠等待服務器響應
self.driver.implicitly_wait(3)
# 改變瀏覽器窗口大學
# self.driver.minimize_window()
def login(self, mode=1):
"""登陸模塊"""
# mode爲預留登陸模式接口
self.driver.get(self.login_url.format(mode))
# 手機號登陸輸入框
phone = self.driver.find_element_by_id('phone')
phone.send_keys(self.login_user)
# 密碼輸入框
password = self.driver.find_element_by_id('pwd')
password.send_keys(self.login_password)
# 登陸按鈕
click = self.driver.find_element_by_id('loginBtn')
click.click()
def seek_classroom(self):
"""尋找課程"""
# 進入到frame嵌入頁面
self.driver.switch_to.frame('frame_content')
room = self.driver.find_element_by_xpath(f'//*[@title="{self.classroom}"]')
room.click()
# 退回到父頁面
self.driver.switch_to.parent_frame()
# 獲取新開啓的頁面的頁柄
time.sleep(1)
return self.driver.window_handles[1]
def look_classroom(self, handles):
"""觀看課程"""
# 新建一個焦點(之後使用到多線程,如果都使用共同的driver會造成共享資源阻塞等問題)
driver = self.driver
# 啓動隱式等待(這裏嵌套網頁較多,且學習通服務器並不是很好)
driver.implicitly_wait(10)
# 將焦點定位到此頁面中
driver.switch_to.window(handles)
# 進入到課程頁面(這裏需要模仿鼠標點擊),啓用行爲鏈
classroom_html = driver.find_element_by_xpath('//span[@class="articlename"]/a')
# 實例化鼠標
mouse = ActionChains(driver)
# 尋找確定點擊目標
mouse.click(classroom_html)
# 執行操作
mouse.perform()
# 獲取所以課程列表
timetable = driver.find_elements_by_class_name('ncells')
# 遍歷所有課程
for classroom in timetable:
# 點擊課程
classroom.click()
room = self.driver.find_element_by_xpath('//*[@title="視頻"]')
# 如果不包含視頻則跳出
if room is None:
break
room.click()
# 視頻採用嵌入式頁面
driver.switch_to.frame('iframe')
driver.switch_to.frame(driver.find_element_by_class_name('ans-attach-online'))
driver.find_element_by_xpath('//button[@title="播放視頻"]').click()
# 返回父頁面
driver.switch_to.parent_frame()
driver.switch_to.parent_frame()
# 網課插件會播放下一集,這裏第一版就不考慮如果切換下一集了。
break
def run(self):
"""運行模塊"""
# 啓動瀏覽器
print('啓動瀏覽器中')
self.start_web()
# 登陸
print('正在登陸')
self.login()
# 尋找課程(新課程會獲取新的頁面)
print('尋找指定課程')
handles = self.seek_classroom()
# 觀看課程
print('開始觀看中')
self.look_classroom(handles)
if __name__ == '__main__':
user = input('請輸入學號或手機號:')
pd = input('請輸入密碼:')
classroom = input('請輸入想要觀看的課程:')
AutoClassroom().run()