绝对安全的简易智慧树刷课脚本!Python代码篇
背景
之前由于疫情原因,全中国的苦逼大学生都被关在家里上网课,然后中国大学MOOC、智慧树等网课平台就成了一生之敌。
以博主为例,博主的马原课在智慧树放了100+个小视频,每个视频中间还穿插问题,防止你无脑刷,结束后还不能自动下一集。由于实在不想浪费时间,博主就做了一个十分安全的简易刷课脚本。
主要思想
智慧树是会对恶意刷课的账号进行警告的,具体判断机制我也不是很清楚,但是我的脚本是利用网页驱动器进行模拟点击,所以除了后台会记录你一天连续看了20小时视频之外(可以调整刷课数量上限防止被查),完全没有任何风险,平台是绝对发现不了你的。
主要使用了selenium,(关于selenium和chrome的版本对应关系请访问下列网址:selenium和chrome版本对应)来模拟点击网页的按钮,从而自动地刷课。(注意:电脑会给你单独开一个chrome图标,不要管即可)
使用说明
将代码copy进python3编译器运行(前置包:tkinter、selenium、re、time,版本主要selenium对应自己的chrome即可)
随后会出现一个极简风的UI(我知道很丑,请谅解博主没啥时间)
然后去自己的课程学习网站复制网址(必须是你看视频的网址),示例如下(没给网课信息打码,罪过罪过)
复制完成后把信息按照UI界面的提示输入(最大刷课数可以不填,默认为无限大,其他不填会有UI提示,但是对学校/学号/密码错误没有提示)
点击那个“智慧树爆炸按钮”,就能生成一个新的驱动器执行的网页。此时网页驱动器就会自动学习了(如果有少数由于博主数据不够而没能发现的弹窗,自行关闭即可)。每节进度达标后会自动跳到下一节,而且可以自动寻找弹窗测验的答案并作答。也就是说,完成后你只需要把它晾那儿就行了。
注意点
该代码仅支持共享课的刷课,不支持翻转课等其他类型的刷课(请谅解,因为博主本人的翻转课很少,就没有设计)
由于某些原因(懒),该程序仅支持通过学校-学号-密码的方式登陆。
由于博主本人是科研狗,也没有打算把这个程序过度实用化,所以没有在程序上投入太多精力,也不打算长期维护。可能会存在一定的bug,大部分bug仅需要重新跑一遍即可。
由于懒,没有加入对密码/账号/学校输入错误的防御机制,大家自己自觉吧(求求大家不要抱着挑刺的态度使用程序,这个程序本来就是我个人用的,本来连UI都么得,所以挑刺是肯定挑不完的,毕竟我没有把它当实际的项目做)
代码仅支持自动跳转下一节课、自动解决弹窗测验。没有办法解决章测试(博主么得数据库)。
如果有问题,可以在评论区提问,欢迎各路大神回答。因为博主本人实在是诸事缠身,可能不能及时解决每一个问题(说实话,过了一个星期我看到的时候,都不好意思回答,因为很可能多此一举,笑哭.jpg)
能自己解决的问题麻烦大家尽量手动解决,比如多一个消息弹窗没关掉(因为博主是以自己的学习经历作为模板设计的程序,有些情况可能没碰过)。
fromseleniumimportwebdriver
import timeimport reimport randomfrom selenium.webdriver.common.action_chainsimportActionChains
import tkinterastk
import tkinter.messageboxtime_percent = re.compile(&9;\d+\.\d+(?=%)&9;)
classtask:
def __init__(self, url, school,account, pwd, max_lesson):self.url = urlself.school = schoolself.account = accountself.pwd = pwdself.max_lesson = max_lessondef window_tk(driver):try:
driver.find_element_by_xpath(&9;/html/body/div[1]/div/div[6]/div/div[1]/button&9;).click()
except:passtry:
driver.find_element_by_xpath(&9;/html/body/div[1]/div/div[3]/div/div[1]/button&9;).click()
except:passtry:
driver.find_element_by_xpath(&9;/html/body/div[1]/div/div[8]/div/div[2]/span/button&9;).click()
except:pass解决弹题测验options = driver.find_elements_by_class_name(&9;topic-item&9;)
print(len(options))foroptioninoptions:
try:
option.click()except:passtry:
answer = driver.find_element_by_class_name(&9;answer&9;).get_attribute(&9;textContent&9;)
answers = re.findall(&9;[A-Z]&9;, answer)
print(answers)foroptioninoptions:
try:
option.click()except:passforiinrange(10):
ifchr(ord(&9;A&9;) + i)inanswers:
options[i].click()time.sleep(1)
buttons = driver.find_elements_by_class_name(&9;btn&9;)
print(len(buttons))forbuttoninbuttons:
try:
button.click()except:passtime.sleep(2)
try:
driver.find_element_by_class_name(&9;playButton&9;).click()
except:passexcept:buttons = driver.find_elements_by_class_name(&9;btn&9;)
forbuttoninbuttons:
try:
button.click()except:pass智慧树警告try:
driver.find_element_by_class_name(&9;el-dialog__headerbtn&9;).click()
except:passdef auto_study(url, school, student_id, pwd, maxlearn=1e9):
opt = webdriver.ChromeOptions()driver = webdriver.Chrome(options=opt)try:
driver.get(url)except:return-1
time.sleep(2)
driver.find_element_by_xpath(&9;/html/body/div[4]/div/div[2]/div[1]/a[2]&9;).click()
driver.find_element_by_xpath(&9;/html/body/div[4]/div/form/div[1]/ul[2]/li[1]/div/input[2]&9;).send_keys(school)
driver.find_element_by_xpath(&9;/html/body/div[4]/div/form/div[1]/ul[2]/li[1]/div/div/div/div[1]/ul/li[1]&9;).click()
driver.find_element_by_xpath(&9;/html/body/div[4]/div/form/div[1]/ul[2]/li[2]/input&9;).send_keys(student_id)
driver.find_element_by_xpath(&9;/html/body/div[4]/div/form/div[1]/ul[2]/li[3]/input&9;).send_keys(pwd)
driver.find_element_by_xpath(&9;/html/body/div[4]/div/form/div[1]/span&9;).click()
time.sleep(1)
driver.back()window_tk(driver)time.sleep(1)
guanbis = driver.find_elements_by_class_name(&9;iconguanbi&9;)
forguanbiinguanbis:
try:
guanbi.click()except:passwindow_tk(driver)time.sleep(3)
ac = ActionChains(driver)ac.move_to_element(driver.find_element_by_class_name(&9;vjs-tech&9;)).perform()
driver.find_element_by_class_name(&9;volumeBox&9;).click()
无限学习开始fortime_slipinrange(int(1e9)):
window_tk(driver)try:
iffloat(re.search(time_percent, driver.find_element_by_class_name(&9;passTime&9;).get_attribute(&9;style&9;)).group()) >90:
try:
driver.find_element_by_id(&9;nextBtn&9;).click()
maxlearn -=1
ifmaxlearn <=0:
return
time.sleep(2)
driver.find_element_by_class_name(&9;volumeBox&9;).click()
except:passtry:
ActionChains(driver).move_to_element(driver.find_element_by_class_name(&9;vjs-tech&9;)).perform()
except:print(&9;fail&9;)
try:
driver.find_element_by_class_name(&9;playButton&9;).click()
except:passexcept:passtime.sleep(3)
driver.find_element_by_id(&9;/html/body/div[1]/div/div[8]/div/div[1]/button&9;).click()
if__name__ ==&9;__main__&9;:
window= tk.Tk()
window.title(&9;智慧树sb&9;)
window.geometry(&9;780x650&9;)
canvas = tk.Canvas(window, width=780, height=821, bd=0, highlightthickness=0)
title1 = tk.Label(window, bg=&9;yellow&9;, width=20, text=&9;待刷课程网址&9;)
title2 = tk.Label(window, bg=&9;yellow&9;, width=20, text=&9;学校&9;)
title3 = tk.Label(window, bg=&9;yellow&9;, width=20, text=&9;学号&9;)
title4 = tk.Label(window, bg=&9;yellow&9;, width=20, text=&9;密码&9;)
title5 = tk.Label(window, bg=&9;yellow&9;, width=20, text=&9;最大刷课数&9;)
canvas.create_window(100,50, width=100, height=40,window=title1)
canvas.create_window(100,150, width=100, height=40,window=title2)
canvas.create_window(100,250, width=100, height=40,window=title3)
canvas.create_window(100,350, width=100, height=40,window=title4)
canvas.create_window(100,450, width=100, height=40,window=title5)
entry1 = tk.Entry(window, bg =&9;white&9;)
entry2 = tk.Entry(window, bg=&9;white&9;)
entry3 = tk.Entry(window, bg=&9;white&9;)
entry4 = tk.Entry(window, bg=&9;white&9;)
entry5 = tk.Entry(window, bg=&9;white&9;)
canvas.create_window(450,50, width=600, height=40,window=entry1)
canvas.create_window(300,150, width=300, height=40,window=entry2)
canvas.create_window(300,250, width=300, height=40,window=entry3)
canvas.create_window(300,350, width=300, height=40,window=entry4)
canvas.create_window(200,450, width=100, height=40,window=entry5)
def start_task():t = task(entry1.get(), entry2.get(), entry3.get(), entry4.get(), entry5.get())ifnot t.url:
tk.messagebox.showinfo(&9;靠,出错了&9;,&9;啊咧咧\n网址还没填呢!&9;)
return
ifnot t.school:
tk.messagebox.showinfo(&9;靠,出错了&9;,&9;啊咧咧\n学校还没填呢!&9;)
return
ifnot t.account:
tk.messagebox.showinfo(&9;靠,出错了&9;,&9;啊咧咧\n学号还没填呢!&9;)
return
ifnot t.pwd:
tk.messagebox.showinfo(&9;靠,出错了&9;,&9;啊咧咧\n密码还没填呢!&9;)
return
ifnot t.max_lesson:
t.max_lesson =10000000
try:
t.max_lesson = int(t.max_lesson)except:tk.messagebox.showinfo(&9;靠,出错了&9;,&9;啊咧咧\n最大课程数必须填正整数哦&9;)
return
out = auto_study(t.url, t.school, t.account, t.pwd, t.max_lesson)ifout ==-1:
tk.messagebox.showinfo(&9;靠,出错了&9;,&9;连接失败!\n请确认网络连接以及链接地址正确\n确认后可再次尝试&9;)
return
button = tk.Button(window, text="智慧树爆炸按钮", command=start_task)
canvas.create_window(400,550, width=100, height=60,window=button)
canvas.pack()window.mainloop()哈哈哈,开个小玩笑!