图书馆自动预约--发送http预约请求
当我们可以识别出来网站的验证码之后,接下来要做的就是发送http请求
这里我们使用到的是requests
最开始我尝试使用scapy,因为scapy是一款很优秀的发包工具,但在http请求这一块可能还是不是很方便
urllib,httplib我也尝试了,但总感觉有一些吃力,最后选择了requests,requests真的超级强大
安装requests
pip install requests
分析网站http请求
一次最基本的预约请求流程
访问网站主页面----获得一个phpsessid
访问登录页面—会在里输入用户名之前系统自动请求验证码资源然后发送验证—输入账号密码验证码–登录成功,获得新的cookie
发送预约请求
这里还是解释清楚一下,避免大家犯跟我一样的错误
最开始我的思路就是,之前请求验证码资源,然后登录,后来发现当我请求验证码资源时,会返回一个msg"错误访问",然后当时不是很理解,后来才发现了原因
缺少PHPSESSID
这个其实很好理解,在登录之前,系统通过每个独特的phpsessid来区分用户,然后登陆的时候通过phpsessid来判断是谁进行的操作,登录成功之后就可以通过真正的用户id比如说这里的学号来区分,同时也可以阻止异常的访问请求,所以为了登录,第一步就是要通过请求这个根页面获得phpsessid,获得之后我们在发送请求就不会报错了,而是会直接把验证码的图片传回来(有兴趣的同学可以自己试一试,尝试直接请求验证码资源,一般都无法成功请求)
所以思路差不多清晰了,下面开始操作
这里推荐使用burpsutie
第一步,请求网站根页面
这一步可能在这里看不出来,但是如果我们待会用requests可以看到请求的时候我们并没有cookie,而是服务器在我们请求这个页面之后发送一个set-cookie:phpseesid,这里的原因可能是我本地的cookie没有失效
第二步,找到登录的时候发送验证码的页面
这个也很好操作,有两个方法
首先都是要访问登录的页面,像这里就是一个按钮
第一种通过firefox等f12查看网络请求,可以找到验证码发送的页面
第二种,burpsuite截断代理
也可以看到请求验证码的页面
如果我们把这个里面的cookie删掉会怎么样
尴尬了,并不影响,但我又发现,如果没有Referer头就会返回异常访问,不过虽然这里不是这样,也是给大家提供个意见,具体还是要看网站,像这里就是通过Referer头来区分的,但有一点是没变的,这里里面的phpsessid就是之后登录时候的sessionid,如果是之前请求过一次了,那么你访问的时候sessionid是不变的,所以不用担心,如果现在你是直接请求的话,那么记着保存sessionid,之后登录要用
第三步,登录请求拦截
可以看到系统怎么发送的登录请求
一定要记住,seesionid,这个是区分不同用户登录用的,也是为了区分验证码,不然后台怎么比对呢
第四步,预约请求拦截
这里可能要多提一下,因为前面3步里请求的资源,我们可以理解为死的,一般网站的主页面,登录页面,以及验证码访问页面是不会动的,但对于一个具体的资源来说,像这里的预约,如果你今天预约的和明天预约的url就不一样,所以这里需要做的就是url分析
其实很好做,找到另一个预约,也发送一次请求,然后通过比对就可以看到差异了,像我们这里get请求的url,/activties后面的2012就是用来区分时间的,每隔一个就会加1,今天是2012,明天就是2013,然后mobile不用管,id对应上
referer头也要修改2012,然后lib是用来区分图书馆,如果需要预约别的就用别的id
然后别忘了修改最下面的redierct_url里面藏得也有2012和12(lib)
开始写代码
首先声明,我python的代码结构可能不好看,如果看的不爽的话,还希望自行调整
第一步,设定定时开启预约
如果想要关机的情况下运行肯定是不可能的,可行的操作就是
设置两个定时任务
定时开机,定时运行python代码,这个具体怎么实现我还在测试,不过我们先把自己内部的定时启动写好
from datetime import time import requests
from PIL import Image
from io import BytesIO import glob import sys import os import time import numpy as np import cv2 import datetime
a=input("你想要预约哪一天,请输入日期,格式为几月:几日") mon=a.split(':')[0] day=a.split(':')[1] a=input("你想要从什么时候开始预约,请输入事件,格式为18:30") hour=a.split(':')[0] min=a.split(':')[1] time_you_want=datetime.datetime(2020, int(mon), int(day),int(hour), int(min), 0)//这里用到了datetime这个时间统计的,time也可以不过这里我用这个还是比较舒服的
userid=input("请输入您的用户名") passwd=input("请输入您的密码") print(time_you_want) while True:
time.sleep(2) flag=0
now=datetime.datetime.now() if flag==1 or time_you_want.day==now.day and time_you_want.month==now.month and time_you_want.hour==now.hour and time_you_want.minute==now.minute:
flag=1//用来循环...防止时间变了以后进不来循环了.. a=yuyue(now,userid,passwd)//调用我们的预约函数,传入了时间和账号密码,然后我的函数定义了一个返回值,如果是1就说明成功啦,否则就失败了
if(a==1):
print("成功抢到啦") sys.exit()
第二部,预约程序
from datetime import time import requests
from PIL import Image
from io import BytesIO import glob import sys import os import time import numpy as np import cv2 import datetime
def yuyue(now,userid,passwd):
daystart=datetime.datetime(2020, 8, 25)//这里是为了计算每一天的预约id,其他情况不一定需要,但我是需要
daypass=(now-daystart).days//这个就是datetime的好处,可以直接计算日期的天数差,分钟差等等
book=1515+daypass//预约id计算
url1="http://10.203.97.155/api.php/activities/{n}/application2?mobile=18123251123&id={n}".format(n=book)//我们请求预约的url
r = requests.get('http://10.203.97.155/home/book/index/type/4')//第一步,请求主页面获得setcookie
coo1=r.headers['Set-Cookie'].split(';')[0]//这里就是提取Set-cookie内容,因为返回的是Set-Cookie:phpssid=123123213213;path='\',然后r.headers['set-cookie']返回的是phpssid=123123213213;path='\',而我们只需要;前部的部分
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0','Accept': 'image/webp,*/*','Accept-Language': 'zh-CN,en-US;q=0.7,en;q=0.3','Accept-Encoding': 'gzip, deflate','Connection': 'close','Referer': 'http://10.203.97.155/home/book/index/type/4','Cookie': coo1,'Cache-Control': 'max-age=0'}//设置相应头,这个可以按照burpsuite里面照抄,最好他有什么你有什么,因为我们有了cookie所以可以正常访问验证码
r=requests.get('http://10.203.97.155/api.php/check',headers=headers)
i = Image.open(BytesIO(r.content))//因为这里返回的内容是二进制图片,就通过image.open打开图片并写入文件夹里
timestamp = int(time.time() * 1e6) //时间戳命名
filename = "{}.png".format(timestamp)
filepath = os.path.join('test', filename)
i.save(os.path.join('test', filename))//保存
im = cv2.imread(filepath)//再读取...不过好像没这个必要.........哈哈哈
preds = get_code(im)//这里get_code就是我们之前写好的读取验证码的函数
a=preds[0]//第一位
b=preds[1]//第二位
c=preds[2]
d=preds[3]
e=str(a+b+c+d)
print(e)//四位验证码
textlen=44+3-len(passwd)//计算下一步post数据长度
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0','Accept': 'application/json, text/javascript, */*; q=0.01','Accept-Language': 'zh-CN,en-US;q=0.7,en;q=0.3','Accept-Encoding': 'gzip, deflate','Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8','X-Requested-With': 'XMLHttpRequest','Content-Length': str(textlen),'Origin': 'http://10.203.97.155','Connection': 'close','Referer': 'http://10.203.97.155/home/book/index/type/4','Cookie': coo1}
data = {'username':userid,'password':passwd,'verify':str(e)}
try:
r=requests.post('http://10.203.97.155/api.php/login',data =data,headers=headers)//post登录请求
coo=r.headers['Set-Cookie']//得到我们想要的最终cookie
coo2=coo1+';redirect_url=%2Fbook%2Fnotice%2Fact_id%2F{n}2Ftype%2F4%2Flib%2F11; '.format(n=book)+coo.split(';')[0]+';'+coo.split(';')[1].split(',')[1]+';'+coo.split(';')[2].split(',')[1]+';'+coo.split(';')[3].split(',')[1]//这一点就是结合burpsuite抓包里面内容拼接成第二部我们需要的cookie
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0','Accept': '*/*','Accept-Language': 'zh-CN,en-US;q=0.7,en;q=0.3','Accept-Encoding': 'gzip, deflate','X-Requested-With': 'XMLHttpRequest','Connection': 'close','Referer': 'http://10.203.97.155/book/notice/act_id/{n}/type/4/lib/11'.format(n=book),'Cookie': coo2}
while True:
r=requests.get(url1,headers=headers)//一直循环发送请求
print (r.json()['msg'])
if r.json()['msg']=='申请成功': return 1
except:
pass
完整代码
图书馆自动预约脚本
azraelxuemo /
library-automatic-reservation
本文地址:https://blog.csdn.net/azraelxuemo/article/details/108237542