【Python】10 自动选课
admin
2024-04-07 17:46:47
0

背景

某些学校的选课规定是只能在特定时间,由上千人同时登陆教务系统,选取数量不充足的课程。
这样做的后果是一部分人登陆不上系统;另一部分人登陆进了系统但已经没有剩余课程了;只有一部分人能够选到课程,但也未必是心仪的课程。

笔者认为这样的选课规则显然是有问题的,在信息化如此发达的现代社会,采取这种“抢课”的方式,仿佛回到原始社会的大草原上追逐猎物,只有精力充沛、运气好的猎人才能追到猎物。
如何保证公平是个永恒的话题。我以为一种可能的方案是预选+摇号,这样或许选到课程的人会更多,而不是集中于少数人。

但如何在现有选课规则下选到课,还得用魔法来打败魔法。在选课结束后,笔者一门课程也没有选到,因此笔者尝试编写一个自动化脚本。脚本每隔固定时间刷新选课网页,当有同学退课时,立即报名。实践表明,这种策略非常有效,三周内成功选到所有七门课程。

祝大家都能选上心仪的课程!

实现

自动化脚本采用Python语言编写,使用selenium库模拟浏览器操作,使用ddddocr库识别验证码。分为自动登录→\rightarrow→刷新网页→\rightarrow→报名课程三个步骤。

自动登录

教务系统通常有验证码,可采用第三方库ddddocr识别后,再自动输入。

def Identify_verifi_code(driver):driver.save_screenshot("D:\\2.png") #//获取页面截图img = Image.open('D:\\2.png') ## 打开2.png文件,并赋值给imgregion = img.crop((650,438,772,491))  #//对获取的截图进行裁剪region.save('D:\\3.png')  #//保存裁剪后的图片ocr = ddddocr.DdddOcr()  #//导入验证码识别with open("D:\\3.png", "rb") as f:img_bytes = f.read()res = ocr.classification(img_bytes)  #//将识别出来的验证码赋给resreturn res

路径和图片名可以按需更改。

刷新网页

def do_login(driver):driver.maximize_window() #将窗口最大化my_action=ActionChains(driver)verifi_code = Identify_verifi_code(driver) #识别验证码# 找到登录框 输入账号密码driver.find_element(By.ID, 'UserId').send_keys(username)#输入用户名driver.find_element(By.ID, 'Password').send_keys(password)#输入密码driver.find_element(By.ID, 'VeriCode').send_keys(verifi_code)#输入验证码time.sleep(6)wait = WebDriverWait(driver, 10) #10秒内每隔500毫秒扫描1次页面变化,当出现指定的元素后结束。wait.until(lambda driver: driver.find_element(By.XPATH, login))driver.find_element(By.XPATH, login).click() #点击登录wait = WebDriverWait(driver, 20) #20秒内每隔500毫秒扫描1次页面变化,当出现指定的元素后结束。wait.until(lambda driver: driver.find_element(By.XPATH, goverment))driver.find_element(By.XPATH, goverment).click()#点击培养管理time.sleep(1)driver.find_element(By.XPATH, lecture_sign_up).click()time.sleep(5)count = 0while True:count = count + 1print(count, end = " ")print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))for lecture in lectures:time.sleep(1)            driver.switch_to.frame('mainFrame')time.sleep(2)driver.find_element(By.CLASS_NAME,lecture_name).send_keys(lecture) #输入讲座题目文本框time.sleep(1)driver.find_element(By.XPATH, query).click() #点击查询time.sleep(2)driver.find_element(By.XPATH, sign_up).click() #点击报名time.sleep(1)driver.find_element(By.XPATH, submit).click() #点击确定time.sleep(1)driver.switch_to.parent_frame()driver.find_element(By.XPATH, lecture_sign_up).click()time.sleep(90)

报名课程

if __name__ == '__main__':# 模拟浏览器打开网站# 添加参数options = Options()# 关闭沙盒启动options.add_argument('--no-sandbox')driver = webdriver.Chrome(chrome_options = options)driver.get(url)# 登录并查询try:do_login(driver)except:driver.quit()driver = webdriver.Chrome(chrome_options = options)driver.get(url)do_login(driver)

完整源码

# -*- coding: utf-8 -*-
#2022/10/28
#自动刷新网站,查询讲座剩余名额,自动报名from selenium import webdriver
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.action_chains import ActionChains
from PIL import Image
import time
import ddddocr
import base64# 只需修改下面三项即可 学号 密码 网址
username = "12345678"
password = "88888888"
url = "https://login.com" lectures = []
# lectures.append("大坝安全技术前沿与创新领域")
# lectures.append("梯级水库群联合调度高效优化方法研究")
# lectures.append("海上风电桩基冲刷与防护研究与前沿")
# lectures.append("高坝泄洪消能研究进展")
# lectures.append("在高原探寻铅锌宝藏")
lectures.append("好氧颗粒污泥的研究和应用:新污染物影响与稳定运行")
# lectures.append("大体积混凝土无人运浇系统模型研究")# F12找到这些位置的 full XPath
login = "/html/body/div[2]/form/div/div[1]/div[5]/button" #登录goverment = "/html/body/div[2]/div/div[1]/div[3]/div[2]/a"#培养管理
lecture_sign_up = "/html/body/div[2]/div/div[1]/div[3]/div[2]/ul/li[14]/a"#博导讲座报名
lecture_name = "textbox-text.validatebox-text.textbox-prompt" #讲座题目
lecture_name_text = "textbox-text.validatebox-text" #讲座题目query = "/html/body/div[1]/div/div/div/div[2]/a/span/span[1]"#查询
sign_up = "/html/body/div[1]/div/div/div/div[3]/div/div[1]/div[2]/div[2]/table/tbody/tr/td[10]/div/a[2]"#报名讲座
submit = "/html/body/div[3]/div[2]/div[4]/a/span"#确定# 识别验证码
def Identify_verifi_code(driver):driver.save_screenshot("D:\\2.png") #//获取页面截图img = Image.open('D:\\2.png') ## 打开2.png文件,并赋值给imgregion = img.crop((650,438,772,491))  #//对获取的截图进行裁剪region.save('D:\\3.png')  #//保存裁剪后的图片ocr = ddddocr.DdddOcr()  #//导入验证码识别with open("D:\\3.png", "rb") as f:img_bytes = f.read()res = ocr.classification(img_bytes)  #//将识别出来的验证码赋给resreturn res# 模拟登陆打卡
def do_login(driver):driver.maximize_window() #将窗口最大化my_action=ActionChains(driver)verifi_code = Identify_verifi_code(driver) #识别验证码# 找到登录框 输入账号密码driver.find_element(By.ID, 'UserId').send_keys(username)#输入用户名driver.find_element(By.ID, 'Password').send_keys(password)#输入密码driver.find_element(By.ID, 'VeriCode').send_keys(verifi_code)#输入验证码time.sleep(6)wait = WebDriverWait(driver, 10) #10秒内每隔500毫秒扫描1次页面变化,当出现指定的元素后结束。wait.until(lambda driver: driver.find_element(By.XPATH, login))driver.find_element(By.XPATH, login).click() #点击登录wait = WebDriverWait(driver, 20) #20秒内每隔500毫秒扫描1次页面变化,当出现指定的元素后结束。wait.until(lambda driver: driver.find_element(By.XPATH, goverment))driver.find_element(By.XPATH, goverment).click()#点击培养管理time.sleep(1)driver.find_element(By.XPATH, lecture_sign_up).click()time.sleep(5)count = 0while True:count = count + 1print(count, end = " ")print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))for lecture in lectures:time.sleep(1)            driver.switch_to.frame('mainFrame')time.sleep(2)driver.find_element(By.CLASS_NAME,lecture_name).send_keys(lecture) #输入讲座题目文本框time.sleep(1)driver.find_element(By.XPATH, query).click() #点击查询time.sleep(2)driver.find_element(By.XPATH, sign_up).click() #点击报名time.sleep(1)driver.find_element(By.XPATH, submit).click() #点击确定time.sleep(1)driver.switch_to.parent_frame()driver.find_element(By.XPATH, lecture_sign_up).click()time.sleep(90)if __name__ == '__main__':# 模拟浏览器打开网站# 添加参数options = Options()# 关闭沙盒启动options.add_argument('--no-sandbox')driver = webdriver.Chrome(chrome_options = options)driver.get(url)# 登录并查询try:do_login(driver)except:driver.quit()driver = webdriver.Chrome(chrome_options = options)driver.get(url)do_login(driver)    

参考资料

[1]零基础十分钟看懂自动打卡程序超详细
[2]selenium元素定位失败常见情况,以及switch_to.frame()的用法
[3]学习笔记:python识别验证码自动登录

相关内容

热门资讯

利润最高预计增长914%!光谷... 今年以来,光通信赛道持续景气。截至7月20日,光谷多家上市公司发布2026年半年度业绩快报显示,营收...
八年IPO长跑重启,南海农商行... 《星岛》见习记者 洪雨欣 深圳报道 等待八年,南海农商银行的A股上市之路迎新进展。 2026年6月...
公募基金2026年二季报全面解... 本篇看点 截至2026年二季度末,公募基金市场总规模约38.6万亿元,较上季度增长5.69%;基金数...
房地产市场出现积极变化 近年来,各地持续优化调整房地产政策,控增量、去库存、优供给,有序放宽购房限制,深化住房公积金制度改革...
【IPO追踪】年内港股最大IP... 近年来光通信企业在资本市场爆火,港股的剑桥科技(06166.HK)、海光芯正(01191.HK)等概...
收购2艘二手箱船,这家“新船东... 由厦门建发集团全资控股的集装箱航运企业Greta完成2艘支线集装箱船收购,持续扩张船队与航线布局。 ...
于东来深夜发文,称胖东来禁止员... 极目新闻记者 王柳钦 7月21日晚,胖东来创始人于东来在社交平台发文,分享胖东来保障幸福生活的制度,...
原创 关... 2026年7月以来,多组城市街景对比视频在各大社交平台持续发酵刷屏,不少网友实拍的城市老商业街、沿街...
万亿市值背后的资金洪流——A股... 7月21日,沪指重新站上3800点,科创50指数飙涨10.73%,AI概念股大幅回升,半导体、存储芯...
原创 别... 最近不少退休的粉丝私信问,手里攒了点养老钱,存银行定期跑不赢通胀,又怕炒股亏钱,该买点啥保值?今天就...
潍柴雷沃智慧农业三度递表港交所... 近日,潍柴雷沃智慧农业科技股份有限公司(以下简称“潍柴雷沃智慧农业”)向香港交易所递交主板上市申请,...
能源早报|中国石化氢能装备产业... 中国石化氢能装备产业集群建设正式启动 7月21日,据中国石化消息,石化机械氢能产业技术交流会暨数智氢...
港股收盘 | 三大指数集体走弱... 财联社7月22日讯(编辑胡家荣)港股三大指数震荡下行。截至收盘,恒生指数跌0.95%,报收24892...
财经调查|老铺黄金深圳门店金价... 深圳商报·读创客户端记者 周良成 7月21日,老铺黄金(HK06181)股价报374.4港元/股,上...
财政部:上半年证券交易印花税1... 来源:财政部网站 2026年上半年财政收支情况 一、全国一般公共预算收支情况 (一)一般公共预算收...
2026CBME,小熊电器正在... 随着00后家长全面接棒生育主力,母婴行业正经历从“粗放增长”到“高质量发展”的关键转型。在这个拐点上...
跨越山海的金融温度——兴业证券... 闽宁协作三十载,山海同心向共富。近日,记者跟随采访团走进兴业证券,探寻这家福建省属国有金融企业如何以...
WAIC大咖说|指尖上的“内卷... “瑞典科学家曾做过一个非常经典的实验,让人去做划火柴的操作,正常情况下只需要几秒钟,但当在他的手指尖...
4747万!大族激光董事长老婆... 来源:市场资讯 来源:财通社 香港豪宅市场回暖之际,一笔来自A股上市公司创始人家族的交易引发市场关注...