【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识别验证码自动登录

相关内容

热门资讯

原创 高... 你有没有发现,几年前人人都在拼命买房,而现在,越来越多人开始思考,房子,到底还是不是财富? 这几年,...
这个春节,中国经济热力值拉满 2026年的春节,注定要在中国消费市场上留下浓墨重彩的一笔。 当9天的超长假期遇上持续加码的政策红利...
2026年中国汽车产业十大趋势... 2025年,中国汽车产业在连续17年产销量稳居全球第一的基础上,再次交出了一份充满变革与挑战的答卷。...
2022年天猫烘焙厨电行业趋势... 今天分享的是:2022年天猫烘焙厨电行业趋势白皮书 报告共计:7页 烘焙厨电迎来新变革:从“功能单一...
春节假期县城网吧人气旺,网吧又... 作者 | 豹变 张经纬 春节假期到来,如果你问回到老家的中青年男性假期玩什么,网吧可能是一个答案。...
上海“小巨人”要敲钟了!商米科... 马年伊始,港股市场就再度迎来一家上海本土科技企业。 据港交所消息,近日,上海商米科技集团股份有限公司...
原创 川... 当特朗普的关税武器让美国最高法院“缴械”时,中国、巴西反而从与美国关税战最大的受害者,变成了“最大的...
原创 刚... 白宫新闻办公室刚向媒体证实,特朗普3月底访华,最高法院转头就砸下一记重锤。 九位大法官裁定,特朗普的...
美国出手 5 亿美元委国石油,... 美国方面透露,已完成首批价值 5 亿美元的委内瑞拉石油出售,后续还将继续推进更多相关交易。这批原油大...
筑强基金集群 精准“滴灌”重点... 当下,产业投资基金已成为发展新质生产力的重要抓手,正发挥着日益重要的作用,如何引来金融活水浇灌“产业...
关于“十五五”期间支持科技创新... 财政部 中央宣传部 国家发展改革委 教育部 科技部 工业和信息化部 民政部 商务部 文化和旅游部 国...
雄安综合保税区全域封关运营 2月24日,海关总署批复同意雄安综合保税区(二期)通过验收,标志着规划面积0.63平方公里的雄安综合...
中加敲定重磅合同,特朗普对华能... 加拿大总理卡尼访华成果丰硕,不仅推动中加经贸合作迈上新台阶,更向其他西方国家释放出积极信号。在美加关...
成都和鸿科技IPO辅导备案,获... 2026年2月14日,证监会官网披露,长江证券已提交《关于成都和鸿科技股份有限公司首次公开发行股票并...
原创 马... 当诺奖得主Demis Hassabis把“推导出广义相对论”设为AGI的及格线时,整个科技圈炸了——...
滴滴春节出行数据:“反向过年”... 流动中国年味浓,人们“马”不停蹄奔向团圆。滴滴出行数据显示,“双向奔赴”成2026年春节出行新看点,...
去年韩国上市公司派息达48万亿... 来源:环球市场播报 周二公布的行业数据显示,受韩国股市前所未有的上涨行情推动,2025年韩国上市公司...
九识智能再获3亿美元融资,估值... 图为九识无人车 36氪获悉,九识智能近日完成新一轮超3亿美元融资,估值突破百亿人民币。这也意味着,就...
央行明日开展6000亿元MLF... 中国人民银行持续加码中长期资金投放,中期借贷便利(MLF)将连续12个月加量续做。 中国人民银行2月...