本文实例为大家分享了Python实现图书馆座位自动预约的具体代码,供大家参考,具体内容如下
配置
通过公网主机定时运行脚本,并发送邮件到自己的qq邮箱,这样在微信就会有消息提示是否预约成功
vim /etc/crontab
设置每到早上7:01自动运行脚本即可
程序流程
(以yuyue.juneberry.cn网站为例)
- get访问登录页面,获取cookie和表单里面的隐藏post字段
- 构造登录post数据,加入从表单里面拿到的隐藏post字段
- post构造后的数据,模拟登录,激活cookie(使cookie有登入权限)
- get访问座位预约界面,激活cookie(使cookie有预约座位权限)
- post预约请求,实现预约座位
- 解析返回结果,判断是否成功,并邮件提醒
要点
- requests库中的requests.session() 能够创建可传递cookies的会话
- 拿到<input type=hidden>的数据并传递到post的数据中
- 抓包判断网站逻辑,筛选出各个请求的参数,并在程序中实现
函数解释
- class FUCK()主类
- _get_date_str(self):获取当前日期,并加上一天,用这个函数构造url的特征字段(图书馆设置提前一天预约座位)
- def _get_order_url(self):构造"预约座位"的post目标url
- def _get_static_post_attr:这个函数解析get请求的返回页面,并从中提取出<input type=hidden>的字段,用于之后的构造post数据
- def login(self):实现登录功能
- def run(self):实现座位预约功能
- def _is_success(self, text):判断预约结果
- def error_log_once(self, text='default error (once)'):
- def error_log(self, text='default error'):这两个函数设置程序状态为"已经出错"或者"未出错"状态(用于自动化运行的时候避免将重复的错误信息写入日志)
- def error_log(self, text='default error'):单次将错误信息写入本地日志
- sendmail.send_mail()邮件发送模块
代码及注释
# /bin/python # -*- coding:utf-8 -*- import time import sys import requests from bs4 import BeautifulSoup from mail import sendmail __author__ = 'xy' # 主类 class FUCK(): def __init__(self, username, password, seatNO, mailto): """ 以四个参数初始化,用户名,密码,要预约的座位号,接受预约结果提醒邮件的邮箱 """ self.username = username self.password = password self.seatNO = seatNO self.mailto = mailto self.base_url = 'http://yuyue.juneberry.cn' self.login_url = 'http://yuyue.juneberry.cn' self.order_url = self._get_order_url() self.login_content = '' self.middle_content = '' self.final_content = '' self.s = requests.session() # 创建可传递cookies的会话 # post data for login self.data1 = { 'subCmd': 'Login', 'txt_LoginID': self.username, # S+学号 'txt_Password': self.password, # 密码 'selSchool': 60, # 60表示北京交通大学 } # post data for order a seat self.data2 = { 'subCmd': 'query', } # 自定义http头,然而我在程序里并没有使用 self.headers = { 'Connection': 'keep-alive', 'Content-Type': 'application/x-www-form-urlencoded', } self.login() self.run() self._is_success(self.final_content) # 怀疑程序出错时,取消下行注释,可打印一些参数 # self._debug() def _get_date_str(self): s = time.localtime(time.time()) ########333 date_str = str(s.tm_year) + '%2f' + str(s.tm_mon) + '%2f' + str(s.tm_mday + 1) date_str = date_str.replace('%2f1%2f32', '%2f2%2f1') .replace('%2f2%2f29', '%2f3%2f1') .replace('%2f3%2f32', '%2f4%2f1') .replace('%2f4%2f31', '%2f5%2f1') .replace('%2f5%2f32', '%2f6%2f1') .replace('%2f6%2f31', '%2f7%2f1') .replace('%2f7%2f32', '%2f8%2f1') .replace('%2f8%2f32', '%2f9%2f1') .replace('%2f9%2f31', '%2f10%2f1') .replace('%2f10%2f32', '%2f11%2f1') .replace('%2f11%2f31', '%2f12%2f1') .replace('%2f12%2f32', '%2f1%2f1') return date_str def _get_order_url(self): return "http://yuyue.juneberry.cn/BookSeat/BookSeatMessage.aspx" + self.seatNO + "&seatShortNo=01" + self.seatNO + "&roomNo=101001&date=" + self._get_date_str() def _get_static_post_attr(self, page_content, data_dict): """ 拿到<input type='hidden'>的post参数,并添加到post_data中 """ soup = BeautifulSoup(page_content, "html.parser") for each in soup.find_all('input'): if 'value' in each.attrs and 'name' in each.attrs: data_dict[each['name']] = each['value'] # 添加到login的post_data中 # self.data2[each['name']] = each['value'] # 添加到order的post_data中 return data_dict def _debug(self): print self.order_url print self.data1 print self.data2 print self.headers print self.s.cookies # print self.login_content # print self.middle_content print self.final_content def login(self): homepage_content = self.s.get(self.base_url).content self.data1 = self._get_static_post_attr(homepage_content, self.data1) r = self.s.post(self.login_url, self.data1) self.login_content = r.content def run(self): # 这个get的意思是:原先的cookie没有预约权限, # 访问这个get之后,会使cookie拥有预约权限,从而执行下一个post self.middle_content = self.s.get('http://yuyue.juneberry.cn/BookSeat/BookSeatListForm.aspx').content # 经测试,这个post只需要一个subCmd的参数就可以正常返回,因此不必根据get内容更新post参数 # self.data2 = self._get_static_post_attr(middle_content, self.data2) # 这个post请求完成了预约功能! r = self.s.post(self.order_url, self.data2) self.final_content = r.content def _is_success(self, text): """ 接受最终的html内容,判断是否成功,并触发日志记录和邮件提醒 """ if '<h5 id="MessageTip">已经存在有效的预约记录。</h5>' in text: self.clear_error_once('[done!] You already ordered a seat!') elif '<h5 id="MessageTip">选择的日期不允许预约。</h5>' in text: self.clear_error_once('[done!] Date is wrong!') elif '<h5 id="MessageTip">所选座位已经被预约。</h5>' in text: self.clear_error_once('[done!] This seat is not available, maybe taken by others!') elif '<h5 id="MessageTip">座位预约成功' in text: self.clear_error_once('[done!] Success! An email is sending to you!') sendmail.send_mail('BJTU Library Seat_NO:' + self.seatNO + 'ordered!', 'Sending by robot. Do not reply this mail!', self.mailto) else: self.error_log_once('Error! 302 to login page') def error_log_once(self, text='default error (once)'): try: is_error_file = open('./isopen_xy.txt', 'r') except: is_error_file = open('./isopen_xy.txt', 'w') if '1' not in is_error_file.read(): print 'writting error to log...' self.error_log(text) else: print 'already written to log' is_error_file.close() sendmail.send_mail('BJTU_Library system error once !', 'error text!') def error_log(self, text='default error'): is_error_file = open('./isopen_xy.txt', 'w') is_error_file.write('1\n') is_error_file.close() f = open("./log_xy.txt", 'a') f.write(time.strftime("%Y-%m-%d %X", time.localtime()) + text + '\n') f.close() def clear_error_once(self, text='success'): print text is_error_file = open('./isopen_xy.txt', 'w') is_error_file.write('0\n') is_error_file.close() if __name__ == '__main__': if len(sys.argv) < 5: print 'Usage: python library.py [username] [password] [seat_NO] [email]' print 'eg. python library.py S13280001 123456 003 XXXX@qq.com\n' print 'Any problems, mail to: i[at]cdxy.me' print '#-*- Edit by cdxy 16.03.24 -*-' sys.exit(0) else: FUCK(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件!
如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
暂无“Python Requests模拟登录实现图书馆座位自动预约”评论...
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
20240901
20240901
- DzintraErliha-Dreamscape(2024)[24Bit-96kHz]FLAC
- 群星.1999-上华世纪国语总冠军4CD【上华】【WAV+CUE】
- 叶丽仪.1992-仙鹤神针电视剧原声音乐专辑【星传真】【WAV+CUE】
- 陈柏宇.2011-QUINQUENNIUM【SONY】【WAV+CUE】
- 《51首热门当红歌曲 十大顶级发烧女声 3CD》[WAV+CUE][1.6GB]
- 《赵传 深受摇滚迷青睐的台湾音乐人 约定》[WAV+CUE][320MB]
- 《庄心妍 实力唱将 发烧音乐精选集》[WAV+CUE][380MB]
- [音展纪念碟]2006年《TAA台湾第十六届国际HI-ENDHI-FI音响展》2cd[WAV]
- 中国音乐地图之听见西藏山歌牧歌酒歌2020[WAV分轨]
- 王宏伟2017-永远的红飘带[太平洋影音][WAV+CUE]
- 费翔.1997-NOW现在【第一中国】【WAV+CUE】
- 新格合唱团.1981-我唱你和2辑(滚石新格民歌系列)【新格】【WAV+CUE】
- 陈柏宇.2011-QUINQUENNIUM【SONY】【WAV+CUE】
- 雨果唱片-《金唛系列-蔷薇依韵琼瑶》WAV
- 陈百强《凝望(2012华纳LPCD45限量版)[DMI]》[WAV整轨]