python实现图书馆研习室自动预约功能


Posted in Python onApril 27, 2018

本文为大家分享了python实现图书馆研习室自动预约的具体代码,供大家参考,具体内容如下

简介

现在好多学校为学生提供了非常良好的学习环境,通常体现在自习教室的设施设备上。对此不得不提一句的就是我们学校的图书馆,随着新图书馆的修建,馆内也设置了多个功能区,每层分为A、B、C、D四个区域,由南北连廊相连,中间由旋转楼梯贯通一至五层。A区为自修区;B区和C区为藏阅一体的社会科学和自然科学书库;D区为专项功能区,包含影视厅、数字媒体创客体验中心、智慧培训教室、云桌面电子阅览室等;B、C区东西连廊设有大小十二间研习室;南北连廊设有休闲阅读区。

上面那段我是从图书馆官网上抄的,不过真的得为学校的图书馆点个赞。回归本篇文章正题,学校免费为广大师生提供了舒适优良设备齐全的研习室。但是这些研习室是需要进行网上预约才能够进入使用,每天的00:00开启下一天的预约,因此要想约到一个时间段(3小时)的研习室,可谓得“挑灯夜战”。当然,在这个过程中手速快将有巨大的优势。如果晚上休息的早,手速又不快,基本上就别想预约到研习室了。刚刚好最近学了一点python爬虫,就打算用爬虫帮我完成这个艰巨的任务了。哈哈哈哈!(ps:防止恶意访问,所有链接就不放了哈)

python实现思路

想想思路还是挺简单的,无非就是登录账号、查找房间、提交预约。那就让我们试试看:

登录账号

首先打开我们研习室预约的登录界面,链接为:U2FsdGVkX19NdfJkghN54Msvy1zl7AucRur/ct0nz4orPI7uLkSDsvuFMgr0fGcO
rn9Z/f8h3bds9w==

python实现图书馆研习室自动预约功能

好吧,这第一步登录账号就非常考验我这个新手了,不过不能怂。通过参考其他一些大佬使用的方法,就是打开firefox的firebug(ctrl+shift+e)查看网络情况,在这个情况下进行一次正常的登录。

python实现图书馆研习室自动预约功能

可以看到我们这里有个post,到时便可以使用python中requests.post方法。

python实现图书馆研习室自动预约功能

为了能够成功的登录,要隐藏自己是个爬虫的身份,在消息头中,可以看到我们的请求头,只要将参数都复制过来,组成自己的headers = {…}来欺骗服务器。

python实现图书馆研习室自动预约功能

看一下参数这一页,这里的表单数据只有三个,分别对应着验证码、账号和密码。将这里的参数复制过来,就可以组成我们的data = {…}。其中需要我们的注意的就是这个验证码,无论是人工“自”能识别,还是机器自动识别,都需要将验证码保存为本地文件。如此一来,就有了一个问题,每访问一次服务器,验证码就会变换。现在让我们好好捋捋思路,首先我们得获得验证码并将其保存在本地,这就需要访问一次服务器,最后我们要提交我们的参数进行登录,这又再一次访问了服务器,这次的验证码和我们获取的验证码已经不是同一个验证码了。在刚刚开始的尝试中我无论如何无法登录服务器,就是两次的验证码不匹配。如何实现第一次获取的验证码和提交时的验证码相一致呢?

这里就需要同一个cookie在上面的几个图中,我们都能看到有个cookie值。要保证同步,这里就需要做到,我们获取验证码时的cookie值和提交账号密码时的cookie值一致。因此,在我的程序中,我先做的一个步骤时先获取一个cookie值,然后将这个cookie值作为headers中的一个参数。登录的思路就是这样了,补充一句,这里的验证码我是自己手动识别的>?<。

查找房间

这个步骤其实是一个无用的步骤,为什么有这个步骤,按照人为预约习惯,我们会产生怎么一个步骤,但是如果使用爬虫,只要成功登录之后就可以直接提交预约的表单。当然,如果要使得自动预约程序更加智能,便可以添加这个步骤,可以查看那些房间是还可以预约的,在这里自定义的补充一些规则。我就略过了。。。

提交预约

同登录一样,我们也手动的提交一次,去查看网络情况,便可以用python模拟这一个过程。在这里我就不在贴图进行解释,这里提交也是用requests.post的方法。不过一点要注意的是,这里的headers和登录时的headers是不一样的,所以在此提醒各位,如果在其他类似的预约程序中可以注意看看不同内容post时的headers是否一致。我在这里就被坑了一会。

#!/usr/bin/env python 
# _*_ coding:utf-8 _*_ 
# 
# @Version : 1.0 
# @Time  : 2018/4/10 
# @Author : 圈圈烃
# @File  : reservation_4.py 

import requests
import re
import json
import datetime
import time


def get_cookies():
  """获得cookies"""
  url = 'http://**************'
  s = requests.session()
  s.get(url)
  ck_dict = requests.utils.dict_from_cookiejar(s.cookies)   # 将jar格式转化为dict
  ck = 'JSESSIONID=' + ck_dict['JSESSIONID']         # 重组cookies

  """获得二维码"""
  path = './code.png'
  get_cookies_headers = {
    'user-anget': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0',
    'Cookie': ck}
  get_cookies_url = 'http://**************'
  code_image = requests.get(get_cookies_url, headers=get_cookies_headers)
  with open(path, 'wb') as fn:
    fn.write(code_image.content)
    fn.close()
    print('验证码保存成功')
  return ck


def login(cookies, hour, minute):
  login_headers = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Encoding': 'gzip, deflate',
    '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',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Content-Length': '45',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Cookie': cookies,
    'Host': '**************',
    'Pragma': 'no-cache',
    'Referer': 'http://**************',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0'
  }
  login_url = 'http://**************'
  login_data = {
    'codeImage': input('请输入验证码:'),
    'uname': '**************',
    'upass': '**************'
  }
  requests.post(login_url, data=login_data, headers=login_headers)

  res = requests.get('http://**************', headers=login_headers)
  reg_h = r'<option value=(.*?)>\d{4}-\d{2}-\d{2}' # 匹配可提供预约的hash
  value_h = re.findall(reg_h, res.text)

  """定时"""
  counter = 0
  while (True):
    now = datetime.datetime.now() # 获取当前系统时间
    if now.hour == hour and now.minute == minute:
      break
    time.sleep(0.5)
    # print(now)
    counter = counter + 1
    if counter == 240:
      res = requests.get('http://**************', headers=login_headers)
      reg_h = r'<option value=(.*?)>\d{4}-\d{2}-\d{2}' # 匹配可提供预约的hash
      reg_t = r'(\d{4}-\d{2}-\d{2})' # 匹配可提供预约的日期
      value_h = re.findall(reg_h, res.text)
      value_t = re.findall(reg_t, res.text)
      with open('./con_log.txt', 'a') as fjs:
        fjs.write(eval(value_h[-1])+' '+value_t[-1]+' '+str(now)+' \n')
        fjs.close()
        print('保存成功')
      counter = 0

  return str(eval(value_h[-1]))


def reservation(day_hash, cookies, stime, etime):
  reservation_data = {
    '_etime': etime, # 结束时间11点,其值为11*60=660
    '_roomid': '1285b3ca77594b3095c7b89d4922553c', # 房间Id
    '_seatno': '',
    '_stime': stime,  # 开始时间8点,其值为8*60=480
    '_subject': '学习', # 研讨主题
    '_summary': '学习', # 研讨大纲
    'ruleId': day_hash,
    'usercount': 3,   # 预约人数
    'users': '**************', # 学号
    'UUID': '**************'
  }

  reservation_headers = {
    'Accept': 'application/json, text/javascript, */*; q=0.01',
    'Accept-Encoding': 'gzip, deflate',
    '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',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Content-Length': '239',
    'Content-Type': 'application/json',
    'Cookie': cookies,
    'Host': '**************',
    'Pragma': 'no-cache',
    'Referer': 'http://**************',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0'
  }
  reservation_js = json.dumps(reservation_data)
  reservation_url = 'http://**************'
  status = requests.post(reservation_url, data=reservation_js, headers=reservation_headers)
  # print(stime, etime)
  # print(status)
  print(status.text)


def main():
  """预约策略一:11:20-20.40"""
  full_stime = ['1060', '870', '680']
  full_etime = ['1240', '1050', '860']
  """预约策略二:10:00-13:00;13:50-16:50;17:40-20:40"""
  stime = ['1060', '830', '600']
  etime = ['1240', '1010', '780']
  cookies = get_cookies()
  day_hash = login(cookies, 0, 0)   # 设定定时时间
  for i in range(0, 3):
    reservation(day_hash, cookies, stime[i], etime[i])


if __name__ == '__main__':
  main()

实现效果

自从学了python,妈妈再也不用担心我抢不到研习室了。在程序中加几行定时的程序之后,便可以在00:00自动帮我预约研习室了。通过测试发现,预约时很大程度上是能够约到房间的,例如在4-12号,约好三个时间段是用了7秒,但是在4-13号居然花了21秒,而且使得一个时间段被其他同学约走了。当然这个程序还需要进一步改进,实现完胜“手速”。

python实现图书馆研习室自动预约功能

补在最后

还有不足,欢迎交流。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现百度关键词排名查询
Mar 30 Python
Python文件的读写和异常代码示例
Oct 31 Python
python 执行shell命令并将结果保存的实例
May 11 Python
Python中.join()和os.path.join()两个函数的用法详解
Jun 11 Python
python 列表递归求和、计数、求最大元素的实例
Nov 28 Python
python+opencv实现高斯平滑滤波
Jul 21 Python
python读取图片任意范围区域
Jan 23 Python
Django forms表单 select下拉框的传值实例
Jul 19 Python
解决pandas展示数据输出时列名不能对齐的问题
Nov 18 Python
用python绘制樱花树
Oct 09 Python
python源码剖析之PyObject详解
May 18 Python
Python答题卡识别并给出分数的实现代码
Jun 22 Python
Python实现去除列表中重复元素的方法小结【4种方法】
Apr 27 #Python
详解python多线程、锁、event事件机制的简单使用
Apr 27 #Python
Python Requests模拟登录实现图书馆座位自动预约
Apr 27 #Python
Python多线程中阻塞(join)与锁(Lock)使用误区解析
Apr 27 #Python
python队列queue模块详解
Apr 27 #Python
浅谈tensorflow1.0 池化层(pooling)和全连接层(dense)
Apr 27 #Python
python线程中同步锁详解
Apr 27 #Python
You might like
用php获取本周,上周,本月,上月,本季度日期的代码
2009/08/05 PHP
PHP遍历数组的几种方法
2012/03/22 PHP
php中禁止单个IP与ip段访问的代码小结
2012/07/04 PHP
Laravel 5.4重新登录实现跳转到登录前页面的原理和方法
2017/07/13 PHP
js类中的公有变量和私有变量
2008/07/24 Javascript
网页禁用右键实现代码(JavaScript代码)
2009/10/29 Javascript
解决jQuery插件tipswindown与hintbox冲突
2010/11/05 Javascript
Javascript中常见的校验如域名、手机、邮箱等等
2014/01/02 Javascript
js隐式全局变量造成的bug示例代码
2014/04/22 Javascript
javascript常见操作汇总
2014/09/03 Javascript
JavaScript函数使用的基本教程
2015/06/04 Javascript
js实现简单计算器
2015/11/22 Javascript
jquery正则表达式验证(手机号、身份证号、中文名称)
2015/12/31 Javascript
javascript基础知识分享之类与函数化
2016/02/13 Javascript
详解XMLHttpRequest(二)响应属性、二进制数据、监测上传下载进度
2016/09/14 Javascript
Node.js测试中的Mock文件系统详解
2016/11/21 Javascript
Vue.js使用$.ajax和vue-resource实现OAuth的注册、登录、注销和API调用
2017/05/10 Javascript
微信小程序 wx.request方法的异步封装实例详解
2017/05/18 Javascript
JavaScript中常见的八个陷阱总结
2017/06/28 Javascript
分享Bootstrap简单表格、表单、登录页面
2017/08/04 Javascript
详解如何让InstantClick兼容MathJax、百度统计等
2017/09/12 Javascript
微信公众号中的JSSDK接入及invalid signature等常见错误问题分析(全面解析)
2020/04/11 Javascript
微信小程序多列表渲染数据开关互不影响的实现
2020/06/05 Javascript
Python中exit、return、sys.exit()等使用实例和区别
2015/05/28 Python
详细介绍Python的鸭子类型
2016/09/12 Python
python使用标准库根据进程名如何获取进程的pid详解
2017/10/31 Python
关于Python数据结构中字典的心得
2017/12/04 Python
对Python实现累加函数的方法详解
2019/01/23 Python
CSS3 transition 实现通知消息轮播条
2020/10/14 HTML / CSS
Html5移动端弹幕动画实现示例代码
2018/08/27 HTML / CSS
新西兰网上购物,折扣店:BestDeals.co.nz
2019/03/20 全球购物
销售团队口号大全
2014/06/06 职场文书
工作表扬信范文
2015/01/17 职场文书
物流业务员岗位职责
2015/04/03 职场文书
Python可视化学习之seaborn绘制矩阵图详解
2022/02/24 Python
JavaScript模拟实现网易云轮播效果
2022/04/04 Javascript