0


基于selenium和pyqt5的自动抢课助手

设计初衷

本设计的初衷在于…好吧我就是有一次没抢到线上课,然后有一个学期上了一学期的线下课…
所以这次铁了心要抢到线上课!!!
所以就有了这个软件的诞生
首先说一下这个东西的不足把,其实挺致命的
他目前的问题就在于,我还没给他添加定时自动抢课的功能,所以说…现在只能手动打开那个软件
然后输上自己的账号密码,选择自己想要选的课程,点击确定之后就可以自动抢课了
目前也没有添加保存密码功能,所以每一次都需要手动再把自己的账号密码打上去…
以后有时间一定会加上去的!🕊
我相信这个工具的功能会越来越完善,ui越来越美观,这也算是我对这个小项目的一个美好的希冀把。

设计思路

本设计主要用到了python的selenium模块,此模块可以用编程来控制浏览器驱动,从而模拟用户的操作
值得一提的是这个模块可以有效的避开一些网站的反爬机制,因为爬虫并不会真正的打开一个网页

而selenium会,selenium的控制思路大概像是JavaScript语言的操作,是对一个页面内的一个个控件来进行操作的
这样“像人的操作”使得这个方法能够用在一些爬虫机制较为高级的网页,或者是那些不太好通过请求来实现目的的需求。

UI部分

UI部分的设计主要通过Python的PYQT5模块,以下为PYQT5的简介:

引用自ChatGPT

PyQt5是一个Python库,用于创建桌面应用程序的图形用户界面(GUI)。
它基于Qt框架,并提供了丰富的工具和类,用于创建功能强大、交互性高的应用程序。
PyQt5具有良好的跨平台性能,可以在多个操作系统上运行。它是一个成熟且广泛使用的库,
拥有强大的社区支持和文档资源。开发者可以使用PyQt5创建各种类型的GUI应用程序,
包括窗口、对话框、按钮、文本框、菜单和工具栏等。它还提供了丰富的绘图功能,
可以进行图表、图像处理和自定义绘图。

我使用的是pycharm里的QTdesigner来实现设计和制作UI,QTdesigner是一款可视化UI制作插件,可以通过拖动和配置的方式
来实现对UI的创建,下图为本软件的用户界面
用户界面

PYQT5中对用户操作事件的绑定,引用了“信号与槽”的概念,,这个机制允许一个对象发出信号,而另一个对象可以捕捉这个信号
并且跳转到对应的槽函数并执行,而信号的概念一般来源于用户的操作或者是捕捉到的别的信号。

逻辑部分

首先我在主程序中定义了一个MyWindow类,其中包括get_user(),get_pass(),confirm()三个方法,三个方法分别对应:
获取学生账号、获取学生密码、获取选课类别和上课类型的功能。
三个方法分别别链接到UI里的账号框、密码框、课程类别和上课平台下拉选择框,当用户在对这些控件进行操作时,他们对应的槽函数
将会获取用户填写的账号、密码和用户选择的选课种类和上课平台并存储到临时变量中,倘若此处将用户填写的信息存储到记忆文件中,
例如文本文档或是数据库,而在下次用户打开软件时先获取文件内用户填写的信息,应该可以实现保存密码的功能。在此便不再赘述,
我没做这个功能绝对不是因为懒!绝对不是!!!🕊
而程序的主逻辑就在于,用户打开程序时,首先创建用户窗口,也就是之前制作的UI,接着等待用户的操作,当用户填写选择完毕,
按下“开始抢课”按钮时,程序跳转到Get_class()函数,此函数则是运用了selenium模块的抢课的实现函数,函数中首先绑定了Edge浏览器驱动文件,
接着开始创建一个web对象,该对象初始化了一个Egde浏览器窗口并显示在用户的电脑屏幕上,然后调用web.get()方法,使用户的浏览器驱动跳转到
对应的界面,通过调用web.find_element()方法、web.send_keys()方法和web.click()方法,实现了查找网页中对应元素并将用户输入过的账号信息填入填写框内
并点击对应按钮的操作。

defGet_class():global Error_flag

    s = Service(".\msedgedriver.exe")# 驱动路径方式如上try:
        web = Edge(service=s)# 打开教务在线
        web.get('http://10.1.1.149')# 摊牌了,我就是cqupt的# 输入信息登录
        web.find_element(By.ID,'userAccount').send_keys(StudentNum)# 账号
        web.find_element(By.ID,'userPassword').send_keys(Password)# 密码
        web.find_element(By.ID,'btn-login').click()# 点击登录
        time.sleep(0.5)except:print("浏览器插件出错!")returntry:if web.find_element(By.XPATH,"/html/body/div[@class ='edu-container-new'] / div[@ class ='edu-content-new'] / form[@ id='loginForm'] / div[@ class ='rt login-form-new'] / div[@ class ='form-item'][1] / font[@ id='showMsg']").text=="该帐号不存在或密码错误,请联系管理员!":# 点击登录
            Error_flag =True
            web.close()
            QMessageBox.about(myWin,"警告","账号或密码错误!")returnexcept:pass
    time.sleep(0.5)
    web.find_element(By.XPATH,"//i[@class='iconfont icon-biyeguanli']").click()# 点击登录
    time.sleep(0.5)# web.find_element(By.XPATH,"//li[@class='open']//li//ul//li[@data-url='/xsxk/xklc_list']").click()  # 点击登录try:
        web.find_element(By.XPATH,"/html/body/div[@id='zccd']/div[@class='edu-aside']/section[@class='edu-sideMenu']/ul[@id='accordion']/li[@class='open']/ul[@class='submenu']/li[3]/div[@class='link']").click()# 点击登录
        web.find_element(By.XPATH,"/html/body/div[@id='zccd']/div[@class='edu-aside']/section[@class='edu-sideMenu']/ul[@id='accordion']/li[@class='open']/ul[@class='submenu']/li[@class='open']/ul[@class='submenu']/li[@class='item-file'][1]/a[@id='NEW_XSD_PYGL_XKGL_NXSXKZX']").click()# 点击登录
        web.get('http://10.1.1.149/jsxsd/xsxk/xklc_list#')except:
        web.close()
        QMessageBox.about(myWin,"警告","暂未开放选课!")returntry:
        web.find_element(By.XPATH,"/html/body/form[@class='table-content layui-form']/div[@class='Nsb_layout_r fixed-middle-item']/table[@id='attend_class']/tbody/tr[2]/td[4]/a").click()# 点击登录except:
        web.close()
        QMessageBox.about(myWin,"警告","暂未开放选课!")return
    time.sleep(0.5)

    web.find_element(By.XPATH,"//input[@value='进入选课']").click()# 点击登录
    web.get('http://10.1.1.149/jsxsd/xsxkkc/comeInGgxxkxk')
    web.switch_to.window(web.window_handles[0])
    time.sleep(0.5)
    web.refresh()whilenot End_flag:try:if web.find_element(By.XPATH,f"//tbody[@role='alert']//tr[{i}]//td[4]").text == Platform and web.find_element(
                    By.XPATH,f"//tbody[@role='alert']//tr[{i}]//td[7]").text == Kind:if web.find_element(By.XPATH,f"//tbody[@role='alert']//tr[{i}]//td[6]").text == Surplus:
                    web.find_element(By.XPATH,f"//tbody[@role='alert']//tr[{i}]//td[@class='center']//div").click()
                    web.switch_to.alert.accept()
                    time.sleep(1)else:
                i = i +1except:continue
    time.sleep(5)

这个操作实现了对目的网页的登录功能,而本项目的核心思路就是查找网页中相应元素并且使用点击或是别的方法,来实现模拟用户的操作
那些繁杂的查找点击操作此处便不再赘述,接下来要讲到的是如何准确的找到页面中想要进行操作的元素,这里我们使用到的是浏览器插件中名叫
XPath Helper的插件,此插件可以非常方便的实现对一个页面中对应元素的快速定位并且返回一个可供Python程序找到的XPath表达式
再这个插件中,只需要用户按住Shift键的同时将鼠标移动到想要获取的元素上方,便可以在对话框中看到该元素的XPath表达式。该插件可以在谷歌浏览器的插件商店里找到。
下图为Xpath使用介绍:
Xpath使用界面

写在后面的话

总体而言,我对这个项目还是不太满意的,首先UI方面没能实现无边框和自动最小化,有失优雅(优雅永不过时(●’◡’●)!),
其次这个项目的逻辑部分没有加上获取时间,所以没有实现到点自动抢课的功能,并且在界面上没有做无感最小化,所以整体来说
只能算一个demo程序,如果要应用到实际中还是需要添加这些功能或是更多功能,比如服务器托管抢课之类的功能,才能更好的实现
解决实际问题的目的。
而本次我最大的收获就是学习到了Python中的selenium模块和PYQT5中UI的制作,并且加深了对信号与槽的理解,锻练了我的Python语法能力。
如果以后有时间的话,我会将这个项目完善好并添加上述的那些功能,如果有什么好的功能和想法,也可以在下面留言~


本文转载自: https://blog.csdn.net/qq_44913672/article/details/130815192
版权归原作者 十岁养家糊口 所有, 如有侵权,请联系我们删除。

“基于selenium和pyqt5的自动抢课助手”的评论:

还没有评论