目录
- 前言
- 一、编写思路
- 二、具体实现
-
- 1. 导入模块
- 2. 登录部分
- 3. 预约部分
前言
??开学第一天学校突然规定图书馆需要预约座位,正好大四开学时间也不是那么紧张,遂和室友突然萌生出写一个自动预约座位的脚本。而显然对于我这种第一次写脚本的超级小白来说,过程是异常艰辛。本篇文章我会把自己的编写流程记录在这里,也算是对这个小脚本的一个总结。第一次写博客缺乏经验,也欢迎大家纠正整个过程中存在的问题。
一、编写思路
??整个编写思路较为简单,首先是登录到学校的图书馆预约管理系统,这里要找到登录界面对应的URL。一般来说找到登录界面浏览器上方网址栏对应的地址即可,不过稳妥起见可以通过查看浏览器自带的抓包分析工具(以Chrome为例,点击右键,选择检查,在检查界面中选择Network)来看请求的URL。登录成功后,先手动操作一遍预约流程,每操作一步在检查界面中的Network部分查看有哪些请求包以及服务器相应的响应。接下来只需要按照抓包工具解析好的各种HTTP请求包的Header,Data等部分,按照预约流程的每一步,来用我们脚本模拟该HTTP请求即可,最后测试一下大功告成!
二、具体实现
1. 导入模块
??由于本脚本涉及网络请求,文本处理等功能,因此需要提前导入如下模块:
2. 登录部分
??登录部分我一开始的思路是向web服务器提交我的用户名与密码,但是通过抓包分析发现每次请求的Header部分都有一个变化的值,导致每次POST请求后,响应头中的Location都没有指向下一个需要请求的地址。我尝试了很长时间也没有成功,于是打算通过浏览器的cookies进行登录。一般来说登录成功后下次再次登录,浏览器会通过本地存储的cookies来完成自动登录过程,无需再次输入密码。如果想查看cookies可以去翻一翻浏览器存储cookies的地方。当然也可以自动登录一下预约网址,通过查看抓包分析工具,找到相应的cookies。这里我的cookies已经作为GET请求的header部分。
??在预约系统上进行手动预约,然后通过浏览器内置的包分析工具获取每一步操作所对应的请求包,同时记得查看对应的相应,通过服务器的相应我们可以查看是否预约成功以及是否需要提供一些验证信息。例如我们学校在预约的时候需要输入验证码,因此提供预约信息后需要对验证码进行处理,不过大致的思路就是如此。整体脚本编写完成后,我还对一些功能进行完善,下面附上全部代码:
# -*- coding = utf-8 -*-import requestsimport jsonimport reimport timeimport datetimedef main(): cur_time = time.strftime("%H:%M:%S", time.localtime()) flag = True while cur_time '12:30:00':if flag is True: print('当前时段暂不可预约') flag = Falsecur_time = time.strftime("%H:%M:%S", time.localtime()) cur_date = datetime.date.today() tor_date = cur_date + datetime.timedelta(days=1) tor_date = str(tor_date) session, header = login() v_number = validation(session, header) reserve(v_number, session, header, tor_date, 50)# 用于验证登录是否成功def verify_login(url): order_page = '' if url == order_page:print('登录成功') else:print('登录失败')# 该登录函数利用客户端的cookie信息完成登录,首次使用需要手动登录并获取cookiedef login(cookies=None): session = requests.session() if cookies is None:cookies = '' # 这里是cookies header = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, " "like Gecko)Chrome/92.0.4515.159 Safari/537.36",'Connection': 'keep-alive','Cookie': cookies } order_page = '' # 这里是预约系统的URl地址 res = session.get(url=order_page, headers=header) verify_login(res.url) return session, header# 该函数用于获得验证码的取值def validation(session, header): valid_page = '' val_params = {'act': 'SetNumberCode' } res = session.get(url=valid_page, params=val_params, headers=header) res_text = json.loads(res.text) pic_num = [] v_number = 0 for i in range(4):tmp = re.search(r'(D*)(d)(D*)', res_text['data'][i])pic_num.append(int(tmp.group(2))) if res_text['data'][4] == '-':v_number = pic_num[0] * 10 + pic_num[1] - (pic_num[2] * 10 + pic_num[3]) else:v_number = pic_num[0] * 10 + pic_num[1] + (pic_num[2] * 10 + pic_num[3]) return v_number# 目前仅支持西土城校区401室,4S-001-4S-072号座位的选择# 若未指定座位号则默认搜索所有可用座位def reserve(v_number, session, header, date, seat_num=None): tot_num = 73 flag = True reserve_page = '' if seat_num is not None:dev_id = seat_num + 105107154res_param = { 'dialogid': '', 'dev_id': str(dev_id), 'lab_id': '', 'kind_id': '', 'room_id': '', 'type': 'dev', 'prop': '', 'test_id': '', 'term': '', 'Vnumber': str(v_number), 'classkind': '', 'test_name': '', 'start': date + ' 08:10', 'end': date + ' 21:00', 'start_time': '0810', 'end_time': '2100', 'up_file': '', 'memo': '', 'act': 'set_resv'}res = session.get(url=reserve_page, headers=header, params=res_param)tmp = json.loads(res.text)if tmp['msg'] == '操作成功!': print('------------------------') print('预约成功') print('座位号:', '4S-%03d' % seat_num) print('------------------------') returnelse: print(tmp['msg']) print('正在搜索其他座位...') flag = False for seat_num in range(20, tot_num):dev_id = seat_num + 105107154res_param = { 'dialogid': '', 'dev_id': str(dev_id), 'lab_id': '', 'kind_id': '', 'room_id': '', 'type': 'dev', 'prop': '', 'test_id': '', 'term': '', 'Vnumber': str(v_number), 'classkind': '', 'test_name': '', 'start': date + ' 08:00', 'end': date + ' 21:00', 'start_time': '0800', 'end_time': '2100', 'up_file': '', 'memo': '', 'act': 'set_resv'}res = session.get(url=reserve_page, headers=header, params=res_param)tmp = json.loads(res.text)if tmp['msg'] == '操作成功!': print('------------------------') print('预约成功') print('座位号:', '4S-%03d' % seat_num) print('------------------------') returnelse: if flag is True: print('搜索全部座位...') flag =来源:喜欢摸鱼的小孩
声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!