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中的数据存储到系统本地的简单方法
Apr 11 Python
利用Python的Django框架生成PDF文件的教程
Jul 22 Python
python实现备份目录的方法
Aug 03 Python
Python排序算法实例代码
Aug 10 Python
Python元组拆包和具名元组解析实例详解
Mar 26 Python
python开头的coding设置方法
Aug 08 Python
Python3 把一个列表按指定数目分成多个列表的方式
Dec 25 Python
Python中import导入不同目录的模块方法详解
Feb 18 Python
sklearn+python:线性回归案例
Feb 24 Python
浅谈python的elementtree模块处理中文注意事项
Mar 06 Python
OpenCV+Python3.5 简易手势识别的实现
Dec 21 Python
python数字图像处理之图像的批量处理
Jun 28 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 防恶意刷新实现代码
2010/05/16 PHP
PHP实现多条件查询实例代码
2010/07/17 PHP
PHP异常Parse error: syntax error, unexpected T_VAR错误解决方法
2014/05/06 PHP
PHP实现登录验证码校验功能
2018/05/17 PHP
Windows上php5.6操作mongodb数据库示例【配置、连接、获取实例】
2019/02/13 PHP
PHP实现本地图片转base64格式并上传
2020/05/29 PHP
保证JavaScript和Asp、Php等后端程序间传值编码统一
2009/04/17 Javascript
jquery dialog键盘事件代码
2010/08/01 Javascript
JavaScript中的property和attribute介绍
2011/12/26 Javascript
利用jquery.qrcode在页面上生成二维码且支持中文
2014/02/12 Javascript
jQuery之字体大小的设置方法
2014/02/27 Javascript
js和jquery如何获取图片真实的宽度和高度
2014/09/28 Javascript
一道优雅面试题分析js中fn()和return fn()的区别
2016/07/05 Javascript
3种不同的ContextMenu右键菜单实现代码
2016/11/03 Javascript
AngularJS框架的ng-app指令与自动加载实现方法分析
2017/01/04 Javascript
如何给ss bash 写一个 WEB 端查看流量的页面
2017/03/23 Javascript
react-native ListView下拉刷新上拉加载实现代码
2017/08/03 Javascript
element ui 表格动态列显示空白bug 修复方法
2018/09/04 Javascript
使用webpack将ES6转化ES5的实现方法
2019/10/13 Javascript
Vue+abp微信扫码登录的实现代码示例
2020/01/06 Javascript
JQuery事件冒泡和默认行为代码实例
2020/05/13 jQuery
原生js实现弹窗消息动画
2020/11/20 Javascript
在Python中使用Mako模版库的简单教程
2015/04/08 Python
在Django的URLconf中使用命名组的方法
2015/07/18 Python
python生成excel的实例代码
2017/11/08 Python
Django权限机制实现代码详解
2018/02/05 Python
python 使用 requests 模块发送http请求 的方法
2018/12/09 Python
django 文件上传功能的相关实例代码(简单易懂)
2020/01/22 Python
python实现word文档批量转成自定义格式的excel文档的思路及实例代码
2020/02/21 Python
Python 私有属性和私有方法应用场景分析
2020/06/19 Python
法国发饰品牌:Alexandre De Paris
2018/12/04 全球购物
.NET remoting的两种通道是什么
2016/05/31 面试题
《晏子使楚》教学反思
2014/02/08 职场文书
企业员工薪酬方案
2014/06/04 职场文书
MySQL去除重叠时间求时间差和的实现
2021/08/23 MySQL
PostgreSQL聚合函数介绍以及分组和排序
2022/04/12 PostgreSQL