用Python webdriver图书馆抢座自动预约的正确姿势

Posted Python学习交流

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用Python webdriver图书馆抢座自动预约的正确姿势相关的知识,希望对你有一定的参考价值。


学校的图书馆需要网上预约。复习考研的人多、疫情座位少,约上一个好点的座位对于我这种经常忘记事情的懒人来说很难。

考虑到老师实验室有一台供我们使用的Windows服务器是不会关机的,正好可以帮我在早上7:00预约系统开启的时候执行程序去预约一个座位。所以产生了这个想法。

微信登录问题


当我没有找到头绪的时候,我偶然间发现学校图书馆开放了另一个入口可以在网页上预约,而这个流程就清晰很多了:


进入网站

输入账号和密码,点击登录按钮

找到座位并选择

Python chrome driver操作



有几个注意的点:


每天早上系统开放的时间有几分钟的差别,需要留时间尝试。

刚开放的时候,系统会很卡,所以很可能会出现获取元素失败之类的情况。

这就要求我们的程序得有足够的鲁棒性(哈哈蛤) 容错能力,不会一下崩了就没用了。

所以我选择用try...except...的方法去进行,写了好多个try, 希望能找到不写这么多Try的更好的方法。


导入库并声明浏览器:

from selenium import webdriver

option = webdriver.ChromeOptions()

url='网址'

local_dir = 'C:\\Users\\Administrator\\Desktop\\librarytest\\' #webdiriver 位置

browser = webdriver.Chrome(local_dir+"chromedriver.exe",options=option)


完整流程:

使用selenium操作非常简单,就是find_element_by_id()和find_element_by_xpath(),主要是看F12去找他们的xpath或者id。


def wholeProcess(browser):

   browser.get(url)

   try:

       btn=browser.find_element_by_xpath("/html/body/div[4]/div[2]/div[2]/dl/input") #找到登录的按钮,如果没找到证明还没到开放时间/系统在崩溃

   except:

       return 1 #1说明预约还没到时候

   '''执行到这里说明打开啦'''

   try:

       btn.click()

       username=browser.find_element_by_id("un")

       password=browser.find_element_by_id("pd")#找到账号密码

       username.send_keys(studentNumber)

       password.send_keys(loginPassword)

       btn=browser.find_element_by_xpath('//*[@id="index_login_btn"]/input')#找到登录按键

       btn.click()

       js=generateJsCode(startTime,endTime)#使用js代码来预约

       res=browser.execute_script(js)

       return 0

   except:

       return 2 #2说明打开了网页,但是遇到了其它问题


用js来预约

找到座位并选择,如果用鼠标操作的话是很繁琐的,包括先找到座位图标,点击,下拉选择开始时间和结束时间,再点击预约,这个过程麻烦不说,主要是容易出错。

而其实一个座位预定的本质其实是提交一个表单。浏览器的前端做了那么多人性化的操作,如可视化座位表、下拉框、温馨提示等,就是为了人使用时好看而又方便,而我们作为计算机就可以饶过他,直接提交表单。这里用的是selenium的execute_script()函数,可以用来执行网页上的js代码。


生成js代码

用F12去观察发现,图书管的表单提交需要下面几步:


$("#date").val("2020-12-10");  

$("#reserveForm#seat").val("13022"); //座位号

$("#start").val("540"); //用分钟表示的时间 :540=9*60 即九点

$("#end").val("1260");

$("#reserveForm").submit();

因此这个函数用来生成js代码:


def generateJsCode(startTime_ori,endTime_ori):

   seatnumber_str = seatId

   startTime_str = str(startTime_ori * 60)

   endTime_str = str(endTime_ori * 60)

   tomorrowTime = (datetime.datetime.now() + datetime.timedelta(days=1)).strftime('%Y-%m-%d')  # 明天

   js = '$("#date").val("' + tomorrowTime + '");$("#reserveForm #seat").val("' + seatnumber_str + '");$("#start").val("' + startTime_str + '");$("#end").val("' + endTime_str + '");$("#reserveForm").submit();'

   return js


主函数——程序出错时尝试:

返回的状态中,如果网页没打开,让他休息10s再尝试,如果是其它原因,那么休息0.5秒就继续尝试:


if __name__=='__main__':

   browser = webdriver.Chrome(local_dir+"chromedriver.exe",options=option)#声明浏览器

   while True:

       state=wholeProcess(browser)

       if state==0: #没出错

           break:

       elif state==1:

           logger.info("打开网页失败")

           time.sleep(10)

       elif state==2:

           logger.info("其它错误")

           time.sleep(0.5)


检测是否成功:

除了上面提到的网页崩溃导致WebDriver报错,还有几种可能导致失败:


座位被人抢了

以上是关于用Python webdriver图书馆抢座自动预约的正确姿势的主要内容,如果未能解决你的问题,请参考以下文章

用webdriver+phantomjs实现无浏览器的自动化过程

Python中Webdriver库的使用

selenium + python自动化测试unittest框架学习webdriver的二次封装

Python+Selenium.webdriver实现WEB端UI自动化测试

windows7 python3.63使用selenium+webdriver 实现自动登录使用过程

python自动化--批量执行测试之生成报告