学习通自动刷课工具(基于Python+Selenium)
媒介 :上海大学学后每个假期都要刷网课(费时劳累),为了俭朴功夫便有了一系列用爬虫机动化实行的办法,高科技变换生存(bushi)。然而上假期实行后并没有记载,而这假期再用创造进修通网站框架结构革新了,旧的便没辙运用了(防了一手),借此时机,重写一下并做个记载
作品目次
一、实行功效
二、东西/库引见
1.selenium引见
2.东西
3.库
三、简直实行
1、引入库
2、图形化界面安排(然而多证明)
3、机动化进程
1.无头欣赏器实行(不表露欣赏器)
2.登录进修通
3.找到对应课程(扶助朦胧查问,运用__contain__因变量)
4.切换窗口句柄
5.找到对应课时(和找课程一致,但只扶助透彻值)
6.机动看视频
7.完备代码请留言或私聊
归纳
一、实行功效
正文引见功效1的实行,功效2、3遥远革新
1、机动化看网课
2、机动化获得各章节标题,并转发至大众号获得谜底
3、按照上头获得的谜底机动答题(因效率不大,拟开拓)
二、东西/库引见
1.selenium引见
selenium是最普遍运用的开源web ui(用户界面)机动化尝试套件之一。它首先由杰森·哈金斯(jason huggins)于2004年开拓,动作thought works的里面东西。selenium扶助跨各别欣赏器,平台和编制程序谈话的机动化。
selenium不妨轻快安置在windows,linux,solaris和macintosh等平台上。其余,它扶助ios(ios,windows mobile和android)等挪动运用步调的os(操纵体例)。
selenium经过运用一定于每种谈话的启动步调扶助百般编制程序谈话。selenium扶助的谈话囊括c,java,perl,php,python和ruby。暂时,selenium web启动步调最受python和c#欢送。selenium尝试剧本不妨运用任何扶助的编制程序谈话举行源代码,而且不妨径直在大普遍新颖web欣赏器中运转。selenium扶助的欣赏器囊括internet explorer,mozilla firefox,google chrome和safari。
selenium运用本领->selenium with python华文翻译文书档案 — selenium-python华文文书档案 2 documentation (selenium-python-zh.readthedocs.io)
2.东西
谈话:python(不得不说小东西首要选择python)
欣赏器:microsoft edge,其余欣赏器也行
欣赏器启动器:自行载入对应欣赏器及本子的启动器
3.库
标为必用的库,不标可视功效采用from selenium import webdriver欣赏器启动from time import sleep等候一定功夫import time用来遏制台输入功夫from lxml import etree领会页面数据import tkinter图形化界面from tkinter import ttk下拉框import tkinter.messagebox动静框from selenium.common.exceptions import nosuchelementexception用来一定特殊处置
三、简直实行
1、引入库
代码如次:
from selenium import webdriverfrom time import sleepimport timefrom lxml import etreeimport tkinterfrom tkinter import ttkimport tkinter.messageboxfrom selenium.common.exceptions import nosuchelementexception
2、图形化界面安排(然而多证明)
代码如次:
def __init__(self):self.window = tkinter.tk()self.window.title("进修通机动刷课")树立窗口巨细winwidth = 300winheight = 200获得屏幕辨别率screenwidth = self.window.winfo_screenwidth()screenheight = self.window.winfo_screenheight()居中表露x = int((screenwidth - winwidth) / 2)y = int((screenheight - winheight) / 2)self.window.geometry("%sx%s+%s+%s" % (winwidth, winheight, x, y))tkinter.label(self.window, text="用户名:").grid(row=1, column=1)self.username = tkinter.stringvar()tkinter.entry(self.window, textvariable=self.username).grid(row=1,column=2)tkinter.label(self.window, text="密码:").grid(row=2, column=1)self.password = tkinter.stringvar()tkinter.entry(self.window, textvariable=self.password,show="").grid(row=2, column=2)tkinter.label(self.window, text="科目名:").grid(row=3, column=1)self.subjestname = tkinter.stringvar()tkinter.entry(self.window,textvariable=self.subjestname).grid(row=3, column=2)tkinter.label(self.window, text="开始课时序号:").grid(row=4, column=1)self.coursenum = tkinter.stringvar()tkinter.entry(self.window, textvariable=self.coursenum).grid(row=4,column=2)tkinter.label(self.window, text="能否表露欣赏器:").grid(row=5, column=1)self.view = tkinter.intvar()tkinter.radiobutton(self.window, text="是", variable=self.view,value=1).grid(row=5, column=2, sticky=&9;w&9;)tkinter.radiobutton(self.window, text="否", variable=self.view,value=2).grid(row=5, column=2, sticky=&9;e&9;)tkinter.label(self.window, text="采用播放速率:").grid(row=6, column=1)self.values = [1, 1.25, 1.5, 2]self.speed = tkinter.stringvar()ttk.combobox(self.window, values=self.values,textvariable=self.speed).grid(row=6, column=2)tkinter.label(self.window, text="能否静音播放:").grid(row=7, column=1)self.sound = tkinter.intvar()tkinter.radiobutton(self.window,text="是",variable=self.sound,value=1).grid(row=7, column=2, sticky=&9;w&9;)tkinter.radiobutton(self.window,text="否",variable=self.sound,value=2).grid(row=7, column=2, sticky=&9;e&9;)tkinter.button(self.window, text="发端刷课", command=self.shuake,width=15).grid(row=8, column=2)self.window.protocol("wm_delete_window",self.close)点击右上角x号封闭界面时触发因变量self.closeself.window.mainloop()def close(self):self.flag = falsetkinter.messagebox.showinfo("close", "退出刷课?")self.window.destroy()封闭页面时触发
实行款式:
3、机动化进程
1.无头欣赏器实行(不表露欣赏器)
不妨挂在后盾实行刷课,但只实用于microsoft edge,未曾试谷歌欣赏器的实行本领,可自行探究
代码如次:
if (self.view.get() == 2):self.view由图形化界面传值edge = {"browsername": "microsoftedge","version": "","platform": "windows","ms:edgeoptions": {&9;extensions&9;: [],&9;args&9;: [&9;--headless&9;,&9;--disable-gpu&9;,&9;--remote-debugging-port=9222&9;,]}}bro = webdriver.edge(executable_path=&9;./msedgedriver&9;, capabilities=edge)else:bro = webdriver.edge(executable_path=&9;./msedgedriver&9;)
executable_path 指的是启动器寄存地方,我寄存在同一目次下,故为 &9;./msedgedriver’
2.登录进修通
sleep(3):安置3秒,提防页面加载太慢而堕落
代码如次:
bro.get(&9;http://passport2.chaoxing.com/login?fid=&newversion=true&refer=http%3a%2f%2fi.chaoxing.com&9;)bro.maximize_window()最大程度窗口bro.find_element_by_id(&9;phone&9;).send_keys(self.username.get())bro.find_element_by_id(&9;pwd&9;).send_keys(self.password.get())bro.find_element_by_id(&9;loginbtn&9;).click()sleep(3)
3.找到对应课程(扶助朦胧查问,运用__contain__因变量)
比方:搜索“(第八期)列宁主义基础道理”只须要输出“马克思”
代码如次:
bro.switch_to.frame(&9;frame_content&9;)page_text = bro.page_sourcefor i in range(1, 20):遍历课程名i = str(i)tree = etree.html(page_text)name_list = tree.xpath(&9;/html/body/div[1]/div/div/div[2]/div/div[2]/div[2]/ul/li[&9; +i + &9;]/div[2]/h3/a/span/text()&9;)sleep(1)name_string = name_list[0]if (name_string.__contains__(self.subjestname.get())):sbuject_xpath = &9;/html/body/div[1]/div/div/div[2]/div/div[2]/div[2]/ul/li[&9; + i + &9;]/div[2]/h3/a/span&9;bro.find_element_by_xpath(sbuject_xpath).click()breakelse:continuesleep(3)
bro.switch_to.frame(‘frame_content’) 这句很要害,由于进修通的框架结构顶用到了iframe,要获得框架内里的标签时必需切换frame,要不会报错“nosuchelementexception”
4.切换窗口句柄
欣赏器窗口句柄:当翻开一个欣赏器并翻开了一个新标签页时,该标签页就会有一个句柄标识(句柄值)。直到你封闭了该标签页,该句柄标识(句柄值)才消逝。
以是,当翻开一个欣赏器并翻开了多个标签页时,封闭一个标签页不会感化其余标签页,即是由于每个标签页有了独一的标识。
当翻开多个页面时须要切换窗口句柄
代码如次:
all_windows = bro.window_handles获得十足窗口句柄bro.switch_to.window(all_windows[-1])切换到结果翻开的窗口
5.找到对应课时(和找课程一致,但只扶助透彻值)
代码如次:
for j in range(1, 20):遍历章节for k in range(1, 15):try:j = str(j)k = str(k)tree = etree.html(page_text)course_num_list = tree.xpath(&9;/html/body/div[5]/div[1]/div[2]/div[3]/div[&9; + j +&9;]/div[&9; + k + &9;]/h3/a/span[1]/text()&9;)course_num_string = course_num_list[0]if (course_num_string == self.coursenum.get()):course_xpath = &9;/html/body/div[5]/div[1]/div[2]/div[3]/div[&9; + j + &9;]/div[&9; + k + &9;]/h3/a/span[1]&9;bro.find_element_by_xpath(course_xpath).click()breakelse:continueexcept (indexerror):breaksleep(3)
6.机动看视频
bro.switch_to.default_content() 归来默许层,前方加入了iframe(“frame_content”)
代码如次:
bro.switch_to.default_content()归来默许层i = 1while true:bro.switch_to.frame(&9;iframe&9;)加入iframetry:num = bro.find_element_by_xpath(&9;//[@id="ext-gen1043"]/div/div/p[1]/strong/span&9;).textexcept (nosuchelementexception):num = "没辙获得"获得章节称呼try:iframe2 = bro.find_element_by_xpath(&9;//iframe[contains(@class,"ans-insertvideo-online")][&9; +str(i) + &9;]&9;)except (nosuchelementexception):if (num == &9;14.3实行共产主义是汗青兴盛的必定趋向&9;):中断章节bro.quit()breakelse:i = 1bro.switch_to.default_content()_item = bro.find_element_by_xpath(&9;//[@id="mainid"]/div[1]/div[2]&9;)bro.execute_script("arguments[0].click();", _item)sleep(2)continuebro.switch_to.frame(iframe2)i += 1try:_item = bro.find_element_by_xpath(&9;//[@id="video"]/button&9;)bro.execute_script("arguments[0].click();", _item)except (nosuchelementexception):print(num, "未平常播放----")continuesleep(1)静音播放if (self.sound.get() == 1):bro.find_element_by_xpath(&9;//[@id="video"]/div[5]/div[6]/button&9;).click()安排倍速if (self.speed.get() == 1):speed = bro.find_element_by_xpath(&9;//[@id="video"]/div[5]/div[1]/button&9;)for i in range(0, 3):speed.click()sleep(0.5)sleep(1)page_text = bro.page_sourcetree = etree.html(page_text)sleep(1)time_list = tree.xpath(&9;//[@id="video"]/div[5]/div[4]/span[2]/text()&9;)sleep(2)time_string = time_list[0]time_list = time_string.split(&9;:&9;)if time_list[-1][0] == "0":time_list[-1] = time_list[-1][1]vedio_time = eval(time_list[1]) + eval(time_list[0])60print(time.strftime("%y-%m-%d %h:%m:%s", time.localtime()),end=&9;----&9;)print(num, "---------", "时间长度:", vedio_time, "秒------", "(",time_list[0], "分", time_list[1], "秒)")if (self.speed.get() == 1):sleep(vedio_time / 2 + 1)else:sleep(vedio_time + 2)bro.switch_to.default_content()
这边的中心是找到寄存视频的谁人iframe,经过领会源码找到了共通点,放视频的框架都有一个class属性含有ans-insertvideo-online,所以不妨经过xpath领会
&9;//iframe[contains(@class,"ans-insertvideo-online")][&9; + str(i) + &9;]&9;
因为一个章节大概不只一个视频,所以须要连接探求直到报错‘nosuchelementexception’,此时加入下一章节。
再有一个详细是进修通把播放按钮‘湮没’起来了(客岁还没有,本年网站革新了,防了一手),所以须要经过javascript来点击。
_item = bro.find_element_by_xpath(&9;//[@id="mainid"]/div[1]/div[2]&9;)bro.execute_script("arguments[0].click();", _item)
其他代码都一个原因,便不复赘述。
7.完备代码请恢复“小东西”
归纳
之上即是对于这个小东西的瓜分,代码中多处用到特殊处置,这不是一个好的风气,但在此只为实行功效,便也就无所谓了。因为这个小东西不过私用,所以代码比拟大略,仍有较多场合须要矫正(懒得改了)。诸位不妨参考一下思绪,计划沿用,不妨的话还请点个赞或留住您珍贵的看法!