当前位置:   article > 正文

python 实现图书馆、体育馆自动预约功能_体育馆预约python网站

体育馆预约python网站

武汉大学体育馆场地可以从网上进行预约,包括羽毛球场,乒乓球场等。预约系统最近是晚上6点开始,可以预约未来2天内的场地。在所有场馆中,室内羽毛球场最为抢手,经常出现系统刚开放所有场地就被“秒杀”的情况。我有几天很想去打羽毛球但是是死活约不到场地,对此我很生气啊,所以就在思考能不能用python制作一个“抢场地机器人”,使其在系统开放预约时准时启动,代替人完成预约任务。

在开始之前,请确保你已经准备好:

  • Python 3.5 或以上;
  • 一个顺手的编辑器 / IDE,如PyCharm、Sublime Text;
  • Python基本语法知识
  • 几个第三方库,requests,剩下time、json、smtplib、email、sys好像是标准库,自带了,无需安装

这篇教程适用于武汉大学体育馆预约系统,链接在这

 

python实现思路

正常手动预约非常简单,先登录然后查找对应时间可用的场地,点击预约即可,这里还有一步比较关键是支付,调用微信支付并完成支付还是比较麻烦的,但是如果本省在系统中有足够的余额便可以一键支付。转换成python来看就更简单了了,首先登陆,在保证账户余额足够的情况下,可以跳过查找位置的问题,直接对向预约的场地发起预约请求,使用余额支付即可。接下来就让我们试试看:

首先是登陆用户,很简单,这个登陆界面链验证码都没有,非常easy,打开浏览器的F12,切换到网络界面,勾选持续日志,输入用户名和密码,就登入了系统,在浏览器的网络界面中(Firefox和Chrome皆可),就可以看到有一个POST请求的参数就是你的用户名和密码,用这个地址就可以用python登陆咯。这是登录后的界面。

 

登录其实就是你把用户名密码提交过去,服务器给你返回一个Token或者Session,使用这个作为cookie的一部分后续服务器就知道你是谁了,所以使用python第一步登录然后就是获取这个Token或者Session。这个服务器使用的是session,登录并获取session的代码这样写。这里注意一点,进行post访问的时候需要一个文件头,来伪装自己的身份,否则原始程序的身份可能会不能访问哦。

  1. def Login(name,pass):
  2. url = 'http://gym.whu.edu.cn/loginAction!UserLogin'
  3. head = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0'}
  4. param = {'name':name, 'password':pass}
  5. session = requests.Session().post(url, headers = head, data = param)
  6. return(session.cookies.get_dict())

登录之后,并成功获取了Session,接下来正常操作应该是找可用场地,但是我们是直接预约嘛,其实是可以跳过找场地这个过程的,直接看看提交预约时,你给服务器发送的数据即可。在浏览器中进行一次提交,找到这个关键的post,可以看到以下几个参数

  1. fdId=32
  2. beginTime=2019-09-21+12:30:00
  3. endTime=2019-09-21+13:30:00
  4. ffId=4
  5. ggId=2
  6. usrId=990
  7. money=7.00
  8. ordTime=2019-09-19+19:30:00
  9. payType=2

研究了下,fdid应该是预定的场地编号,后面是起止时间,然后ffid是运动类型编号,ggid是场馆编号,usrId应该是使用cookie的用户账户,尝试登陆其他账户也是990,就不用了管了,接下来花钱的金额,后面ordtime应该就是请求发出的时间,最后支付类型,使用python把这些参数发出即可。函数这么写

  1. def Res(JSESSIONID, fdId):
  2. Time = '2019-09-21'
  3. url = 'http://gym.whu.edu.cn/OrderAction!bookOrder?deposit=0.00'
  4. head = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0',
  5. 'Host': 'gym.whu.edu.cn',
  6. 'Accept': 'application/json, text/javascript, */*; q=0.01',
  7. 'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
  8. 'Accept-Encoding': 'gzip, deflate',
  9. 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
  10. 'X-Requested-With': 'XMLHttpRequest',
  11. 'Content-Length': '150',
  12. 'Connection': 'keep-alive',
  13. 'Referer': 'http://gym.whu.edu.cn/wechat/booking/gymHome.jsp?ggId=4',
  14. 'Cookie': 'iPlanetDirectoryPro=kZtrSgx3gCXpsQecF4Elfb; JSESSIONID=' + JSESSIONID}
  15. strtime = time.strftime('%Y-%m-%d+%H%%3A%M%%3A%S',time.localtime(time.time()))
  16. param = 'fdId=' + fdId + '&beginTime=' + Time +'+19%3A30%3A00&endTime=' + Time +\
  17. '+20%3A30%3A00&ffId=18&ggId=4&usrId=990&money=10.00&ordTime=' + strtime + '&payType=2'
  18. res = requests.post(url, data = param, headers = head, verify=False)
  19. return(res)

这儿我把头写的完善了点, 把乱起八糟的东西都加上了,还有最重要的session。仔细看代码,有些不一样

这里敲黑板,这里坑害了我好久,让我尝试无数遍的地方。

哪里不一样呢?在参数中的时间那,本来是冒号的地方我改成了%3A,参数直接写成冒号传入,报错Struts Problem Report,这个错误害的我好苦,网上并没有解决方案。最后试了许久想到是不是编码的问题,所以换了下编码方式,具体想了解Unicode和UTF-8以及ANSI的同学可以自行百度。换成这个传入参数柳暗花明又一村,终于成功了,击掌!!!!

最后,预定成功了,我得知道啊,上网查了下,我微信QQ都不如发邮件方便,这个都是网上查的,直接上代码吧。

  1. def send(flag, mess): #传入flag(成功与否的标志),mess(预定的位置时间)
  2. mail = smtplib.SMTP()
  3. mail.connect("smtp.qq.com") # 连接 qq 邮箱的SMTP服务
  4. mail.login("x1@qq.com", "xxxx") # 账号和授权码
  5. if flag == 1:
  6. print('预定成功')
  7. message = MIMEText(mess) # 邮件内容
  8. message['Subject'] = Header('羽毛球场预定成功提醒') # 邮件主题
  9. mail.sendmail("x1@qq.com", ["x2@qq.com"], message.as_string()) # 发送账号、接收账号和邮件信息

授权码查找方法如上所示。

好了,基本主要功能就完成了,在指定时间把程序跑起来就可以了,不需要掐好时间,我的想法是没到时间代码就沉睡,每10s判断一下到时间没,到开始预约的前一分钟,开始登陆预约操作,直到预约成功,发送邮件并跳出循环,结束程序,代码就完成了。

  1. if __name__ == '__main__':
  2. print('sleep_now', end = '') #未到时间,休眠
  3. while True:
  4. strtime = time.strftime('%H%M',time.localtime(time.time()))
  5. if strtime == '1759':
  6. print('Start Booking')
  7. res = Res(jsid, '36')
  8. trytime = 1
  9. while res.headers['Content-Length'] != '1':
  10. trytime += 1
  11. res = Res(jsid, '36')
  12. time.sleep(1)
  13. if trytime > 20:
  14. send(0, '预定失败')
  15. print(trytime)
  16. sys.exit()
  17. send(1, '预定成功')
  18. break
  19. else:
  20. time.sleep(10)
  21. print('.', end = '')

最后,放一个全部代码吧,方便大家使用

  1. import requests
  2. import time
  3. import json
  4. import smtplib
  5. from email.mime.text import MIMEText
  6. from email.header import Header
  7. import sys
  8. def Login(name,pass):
  9. url = 'http://gym.whu.edu.cn/loginAction!UserLogin'
  10. head = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0'}
  11. param = {'name':name, 'password':pass}
  12. session = requests.Session().post(url, headers = head, data = param)
  13. return(session.cookies.get_dict())
  14. def Res(JSESSIONID, fdId):
  15. Time = '2019-09-21'
  16. url = 'http://gym.whu.edu.cn/OrderAction!bookOrder?deposit=0.00'
  17. head = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0',
  18. 'Host': 'gym.whu.edu.cn',
  19. 'Accept': 'application/json, text/javascript, */*; q=0.01',
  20. 'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
  21. 'Accept-Encoding': 'gzip, deflate',
  22. 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
  23. 'X-Requested-With': 'XMLHttpRequest',
  24. 'Content-Length': '150',
  25. 'Connection': 'keep-alive',
  26. 'Referer': 'http://gym.whu.edu.cn/wechat/booking/gymHome.jsp?ggId=4',
  27. 'Cookie': 'iPlanetDirectoryPro=kZtrSgx3gCXpsQecF4Elfb; JSESSIONID=' + JSESSIONID}
  28. strtime = time.strftime('%Y-%m-%d+%H%%3A%M%%3A%S',time.localtime(time.time()))
  29. param = 'fdId=' + fdId + '&beginTime=' + Time +'+19%3A30%3A00&endTime=' + Time +\
  30. '+20%3A30%3A00&ffId=18&ggId=4&usrId=990&money=10.00&ordTime=' + strtime + '&payType=2'
  31. res = requests.post(url, data = param, headers = head, verify=False)
  32. return(res)
  33. def Send(flag, mess): #传入flag(成功与否的标志),mess(预定的位置时间)
  34. mail = smtplib.SMTP()
  35. mail.connect("smtp.qq.com") # 连接 qq 邮箱的SMTP服务
  36. mail.login("x1@qq.com", "xxxx") # 账号和授权码
  37. if flag == 1:
  38. print('预定成功')
  39. message = MIMEText(mess) # 邮件内容
  40. message['Subject'] = Header('羽毛球场预定成功提醒') # 邮件主题
  41. mail.sendmail("x1@qq.com", ["x2@qq.com"], message.as_string()) # 发送账号、接收账号和邮件信息
  42. if __name__ == '__main__':
  43. print('sleep_now', end = '') #未到时间,休眠
  44. while True:
  45. strtime = time.strftime('%H%M',time.localtime(time.time()))
  46. if strtime == '1759':
  47. print('Start Booking')
  48. res = Res(jsid, '36')
  49. trytime = 1
  50. while res.headers['Content-Length'] != '1':
  51. trytime += 1
  52. res = Res(jsid, '36')
  53. time.sleep(1)
  54. if trytime > 20:
  55. Send(0, '预定失败')
  56. print(trytime)
  57. sys.exit()
  58. Send(1, '预定成功')
  59. break
  60. else:
  61. time.sleep(10)
  62. print('.', end = '')

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/307120
推荐阅读
相关标签
  

闽ICP备14008679号