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

相关内容

热门资讯

“双标”换卡背后,银行还需多些... 新华社记者 颜之宏、杨深深 持到期银行卡和身份证去银行网点换新卡,却被要求“必须交回旧卡才能取新卡”...
“离境退税2.0”带动“中国购... 【环球时报综合报道】编者的话:5月18日,商务部等6部门联合发布《关于加力优化离境退税措施扩大入境消...
一年烧掉2000亿、市值蒸发3... 商业润点 |Biz Run Review 三国归晋,用了六十年。即时零售的"三国杀",才刚刚开局...
原创 金... 2026年5月22日,国内黄金市场呈现出令人咋舌的价格鸿沟。基础金价徘徊在每克995.3元,而回收价...
原创 人... SpaceX的星舰V3终于在全球瞩目中成功升空。北京时间5月23日清晨,这颗高达124米的巨型火箭顺...
原创 被... 5月19日,欧洲议会掀起了一场引人注目的风暴,以压倒性的票数通过了最新的钢铁进口规定。 这套规则...
光纤量价齐升,烽火通信加快布局... 烽火通信(600498)5月22日披露的投资者关系活动记录表显示,公司于5月21日参加了中国信息通信...
原创 突... 今天5月24日一大早,打开行情一看,国际现货黄金报4508.25美元/盎司,单日跌了26.68美元,...
企业快讯 | 携手联通!狄耐克... 狄耐克 厦门总商会副会长企业 厦门狄耐克智能科技股份有限公司 与中国联通厦门分公司 将5G智慧“嵌入...
美银策略师警告:SpaceX与... 环球网 据彭博社报道,美国银行首席投资策略师迈克尔·哈特奈特(Michael Hartnett)最新...
卸任55天后,知名基金经理任相... 【导读】卸任55天后,知名基金经理任相栋“奔私”谜底揭晓 见习记者 闫军 知名基金经理任相栋“奔私”...
原创 大... “免签+手机刷一切”就能让老外连夜订机票?2026年一季度,阿根廷人来华暴涨九倍,北京三源里菜市场三...
从泰山顶峰掉落!“大佬背后的大... 文/刘工昌 他曾是柳传志的“大哥”,助力联想完成混合所有制改革;是史玉柱眼中的“贵人”,帮他东山再起...
原创 2... 最近网上流传出一份2030年GDP10强预测榜单,其中一些城市位次的变化也挺有趣的。上海排在第一,深...
原创 全... 2026年3月的全球美债市场迎来剧烈变动,彻底打破了长期稳定的持仓格局。 根据美国财政部发布的国际资...
全球都在给这几只“疯牛”烧钱 近段时间,AI行情再次成为全球资本市场主线,但舞台中央的“主角”发生了变化:投资者不再只偏好云厂商和...
【财闻联播】“硬刚监管”?老虎... ★ 宏观动态 ★ 商务部:1—4月全国吸收外资2876.9亿元人民币 据商务部网站,2026年1—4...
燕京啤酒营收净利双增:U8增速... 蓝鲸新闻5月22日讯(记者 朱欣悦)燕京啤酒(000729.SZ)打了一个翻身仗。 2025年燕京啤...
原创 帮... 老铁们,这周有个事儿挺有意思,估计不少基民都看懵了:都说科技是主线,芯片是未来,可数据显示,年内火爆...
4家银行AIC现身存储巨头股东... 近日,资本市场热度颇高的两家存储巨头长鑫科技集团股份有限公司(以下简称“长鑫科技”)、长江存储控股股...