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中使用dict和set方法的教程
Apr 27 Python
Python中的hypot()方法使用简介
May 18 Python
Python实现基本线性数据结构
Aug 22 Python
Python绘制七段数码管实例代码
Dec 20 Python
Python SQLite3简介
Feb 22 Python
利用python实现微信头像加红色数字功能
Mar 26 Python
numpy matrix和array的乘和加实例
Jun 28 Python
python发送告警邮件脚本
Sep 17 Python
python制作抖音代码舞
Apr 07 Python
python设计微型小说网站(基于Django+Bootstrap框架)
Jul 08 Python
Python爬取视频(其实是一篇福利)过程解析
Aug 01 Python
Python可以用来做什么
Nov 23 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
解决jquery的.animate()函数在IE6下的问题
2010/12/03 Javascript
JS获取页面窗口大小的代码解读
2011/12/01 Javascript
javascript显示中文日期的方法
2015/06/18 Javascript
浅谈setTimeout 与 setInterval
2015/06/23 Javascript
Javascript实现检测客户端类型代码封包
2015/12/03 Javascript
String字符串截取的四种方式总结
2016/11/28 Javascript
JS中如何实现Laravel的route函数详解
2017/02/12 Javascript
bootstrap基本配置_动力节点Java学院整理
2017/07/14 Javascript
Angular使用Md5加密的解决方法
2017/09/16 Javascript
nodejs发送http请求时遇到404长时间未响应的解决方法
2017/12/10 NodeJs
vue项目中api接口管理总结
2018/04/20 Javascript
微信小程序之判断页面滚动方向的示例代码
2018/08/30 Javascript
原生JS实现的放大镜特效示例【测试可用】
2018/12/08 Javascript
解决vue语法会有延迟加载显现{{xxx}}的问题
2019/11/14 Javascript
微信小程序canvas截取任意形状的实现代码
2020/01/13 Javascript
JS数组扁平化、去重、排序操作实例详解
2020/02/24 Javascript
JS手写一个自定义Promise操作示例
2020/03/16 Javascript
Python实现检测文件MD5值的方法示例
2018/04/11 Python
python爬虫URL重试机制的实现方法(python2.7以及python3.5)
2018/12/18 Python
python 画条形图(柱状图)实例
2020/04/24 Python
Python爬虫如何破解JS加密的Cookie
2020/11/19 Python
HTML5实现简单图片上传所遇到的问题及解决办法
2016/01/20 HTML / CSS
Get The Label中文官网:英国运动时尚购物平台
2017/04/19 全球购物
LN-CC英国:伦敦时尚生活的缩影
2019/09/01 全球购物
SCHIESSER荷兰官方网站:德国内衣专家
2020/10/09 全球购物
技术人员面试提纲
2013/11/28 职场文书
中学生班主任评语
2014/01/30 职场文书
大学生个人实习的自我评价
2014/02/15 职场文书
工资收入证明
2014/10/07 职场文书
单位租房协议书样本
2014/10/30 职场文书
2014财务部年度工作总结
2014/12/08 职场文书
党风廉正建设责任书
2015/01/29 职场文书
幼儿园心得体会范文
2016/01/21 职场文书
2019朋友新婚祝福语精选
2019/10/10 职场文书
深入浅析Redis 集群伸缩原理
2021/05/15 Redis
MySQL数据库查询之多表查询总结
2022/08/05 MySQL