【Python】10 自动选课
创始人
2024-01-20 23:40:32
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识别验证码自动登录

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...