一、簡介
僅供學習討論,請勿用於刷課!
本文主要介紹使用Python3+Selenium+Chromedriver來實現一個自動刷網課的小腳本,目標網課平臺是智慧樹。
二、環境配置
筆者的平臺是Win10,其它平臺未做嘗試。需要配置以下環境:
- pip install selenium
- 下載ChromeDriver(注意下載與自己的Chrome瀏覽器相對應的版本),並將ChromeDriver.exe放置在Chrome.exe相同目錄下,並將該路徑添加至環境變量中。(如筆者的路徑是C:\Program Files (x86)\Google\Chrome\Application)
三、Selenium與ChromeDriver簡單介紹
- Selenium 是一個用於Web應用程序自動化測試的工具,它直接運行在瀏覽器中,就像真正的用戶在操作一樣。
- Selenium支持衆多瀏覽器,其中就包括Chrome,搭配ChromeDriver對Chrome進行驅動即可模擬用戶操縱Chrome進行操作。
- Selenium支持許多語言,比如python直接通過pip install selenium即可下載selenium包
四、Show me the code
Selenium的教程網上已有許多,讀者可以自行搜索。下面直接上代碼,代碼僅一百行,用到的也都是基本操作,僅供讀者參考,運行中可能由於網絡延遲等各種情況拋出異常,讀者可自行做相應修改。附上github鏈接
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException, ElementClickInterceptedException
import time
from selenium.webdriver.common.action_chains import ActionChains
debug = True
def log(text):
if debug:
print(text)
else:
pass
if __name__ == '__main__':
url = 'https://passport.zhihuishu.com/login?service=https://onlineservice.zhihuishu.com/login/gologin'
course = "" #課程名稱
university = "" #學校名稱
student_code = "" #學號
passport = "" #密碼
count = 2 #要看的集數
browser = webdriver.Chrome()
wait = WebDriverWait(browser, 10)
browser.get(url)
#添加cookie減少彈窗數量
browser.add_cookie({'name' : 'cookieServer', 'value' : '1', 'domain' : '.zhihuishu.com'})
browser.add_cookie({'name' : 'warningTip', 'value' : '1', 'domain' : '.zhihuishu.com'})
#登錄操作
log('開始登錄')
wait.until(EC.element_to_be_clickable((By.LINK_TEXT, '學號'))).click()
wait.until(EC.presence_of_element_located((By.ID, 'quickSearch'))).send_keys(university)
wait.until(EC.presence_of_element_located((By.ID, 'clCode'))).send_keys(student_code)
wait.until(EC.presence_of_element_located((By.ID, 'clPassword'))).send_keys(passport)
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#schoolListCode > li > b > font'))).click()
wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'wall-sub-btn'))).click()
#進入對應課程
log('進入課程')
wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'courseName')))
course_list = browser.find_elements_by_class_name('courseName')
flag = -1
for index,item in enumerate(course_list):
if item.text == course:
flag = index
break
if flag != -1:
course_list[index].click()
else:
log("未找到對應課程")
exit()
#關閉成績提醒(可能會被彈題窗口擋住,要處理這種情況)
try:
wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'popboxes_close'))).click()
except ElementClickInterceptedException:
pop_chapter = browser.find_element_by_class_name('tanti_popchapter')
ActionChains(browser).move_to_element(pop_chapter).click().perform()
browser.find_element_by_link_text('關閉').click()
wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'popboxes_close'))).click()
new_episode = True
while count > 0:
time.sleep(5)
#模擬鼠標劃入播放窗口的操作,喚起底部控制欄
video_area = wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'videoArea')))
#識別當前狀態(播放、暫停、播放完、問題彈出)
try:
playButton = browser.find_element_by_class_name('playButton')
except NoSuchElementException:
if new_episode:
#調至1.5倍速
ActionChains(browser).move_to_element(video_area).perform()
wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'speedBox'))).click()
wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'speedTab15'))).click()
log('設置1.5倍速')
#調靜音
wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'volumeBox'))).click()
log('設置靜音')
#設置標誌位
new_episode=False
else:
#判斷是否有彈窗彈出或是播放完
try:
pop_chapter = browser.find_element_by_class_name('tanti_popchapter')
except NoSuchElementException:
pass_time = browser.find_element_by_class_name('passTime')
ActionChains(browser).move_to_element(video_area).perform()
if pass_time.get_attribute('style') == 'width: 100%;':
count = count - 1
if count != 0:
wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'nextButton'))).click()
new_episode=True
log('播放下一集')
else:
log('繼續播放')
playButton.click()
else:
ActionChains(browser).move_to_element(pop_chapter).click().perform()
browser.find_element_by_link_text('關閉').click()
log('關閉彈窗')
print('已經看完目標集數,程序退出')