疫情自动打卡

主要涉及到一个查询参数的逆向.疫情填报打卡,之前用selenium写过,不过比较笨重.

现在直接使用requests.

爬虫的精髓应该是js逆向,反爬技术.
使用python的简单之处就是利用方法简单的库,cookie自动保存,留给我们的就是去逆向,多线程处理等等.

开始

首先进入官网

西北工业大学

打开检查,一般流程是发送一个GET请求,有了cookie.如果你发现响应没有set-cookie,而请求直接就有了cookie,这一般是浏览器缓存了,可以清除一下cookie.

image-20220102171907498

这就是响应,可以看到有了set-cookie,这很重要,直接提交表单的话没有cookie,很可能失败(要说为什么不是一定,这与你调的第三方包有关).

image-20220102171754941

然后输入账号密码,查看又发了什么请求,通常会发一个POST.

打开筛选器 method:POST查看

image-20220102172509367

当看到POST请求时有必要查看PAYLOAD,也就是携带的数据.

image-20220102172603819

构造请求时直接把这个表单发过去就行了.

再看看响应头又有set-cookie说明这个很有用,因为给了你cookie.

image-20220102172706501

这样登录之后就有了基本的cookie

进入疫情填报

然后进入疫情填报界面疫情每日填报

正常一波操作:打开审查,刷新,查看重要的请求(一般是jsp或者js啥的)

看到了熟悉的set-cookie

image-20220102173029972

说明这个url是需要get的,同时查看响应发现有很多个人信息,包括姓名.

注意一下:因为我们登陆时只输入了学号和密码,如果后面需要姓名,可以通过这种方法获取响应提取出姓名.

这里就可以利用正则提取出姓名.

1
2
name_info = s.get(get_name_url, headers=headers).text
name = re.search(r'姓名:(.*)<', name_info).group(1)

同时我们又可以发现还有POST请求

image-20220102173401933

查看payload,有一个

1
actionType: getRoles

看不出有什么特别的作用,可以不用post.

最后

然后点击每日填报,又进入新的页面,查看有没有什么请求

筛选jsp,我们到这里就可以知道这个网站的架构了,利用jsp(不过这是常见的方法)

可以发现一个请求jrsb.jsp,貌似没什么特别作用.

image-20220102173804950

不过可以看看响应的预览,后面可能会用于提取一些数据啥的.

勾选已检测,提交表单.

可以查看新的请求

image-20220102174221779

这就是提交表单的POST.

查看Payload,重点是sign和timeStamp.表单数据正常贴过去就行.

主要是sign和timeStamp数据如何获取.

image-20220102174413097

接下来说说这个重点

重点

直接全局搜索sign或者其他关键词,这里的要点是不能把之前的清空了,也就是查询字符串参数与之前的响应有关.

image-20220102174720756

结果惊奇的发现这个字段在jrsb.jsp的响应里,url就是这个字段,推测是后台java生成后发过来的.

image-20220102175014649

提取出来就行了.

1
2
query_info = s.get(get_query_url, headers=headers).text
info = re.search(r'sign=(.*?)&timeStamp=(\d*)', query_info)

后面post需要params的参数,也就是post需要data表单数据,也需要params的字符串查询参数.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
post_url = 'http://yqtb.nwpu.edu.cn/wx/ry/ry_util.jsp?' + info.group()
params = {
'sign': sign,
'timeStamp': timestamp
}
data = {
'hsjc': '1',
'xasymt': '1',
'actionType': 'addRbxx',
'userLoginId': sno,
'szcsbm': '1',
'bdzt': '1',
'szcsmc': '在学校',
'sfyzz': '0',
'sfqz': '0',
'tbly': 'sso',
'qtqksm': '',
'ycqksm': '',
'userType': '2',
'userName': name,
}
# 这里要加一下请求源 必要
headers.update({
'Referer': 'http://yqtb.nwpu.edu.cn/wx/ry/jrsb.jsp',
'Origin': 'http://yqtb.nwpu.edu.cn',
})
r = s.post(post_url, headers=headers, data=data, params=params)

最后要加一下请求的referer

 Referer 请求头包含了当前请求页面的来源页面的地址,即表示当前页面是通过此来源页面里的链接进入的

如果不加测试发现过不了,应该是服务器有检测.

这样整个代码基本就完成了.

源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import json
import requests
import re


def login(sno, pwd):
s = requests.Session()
# CAS系统登录报文
login_url = 'https://uis.nwpu.edu.cn/cas/login'
be_student_url = 'http://yqtb.nwpu.edu.cn/wx/xg/yz-mobile/qj_util.jsp'
get_name_url = 'http://yqtb.nwpu.edu.cn/wx/xg/yz-mobile/index.jsp'
get_query_url = 'http://yqtb.nwpu.edu.cn/wx/ry/jrsb.jsp'
headers = {
'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',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62',
}
data = {
'username': sno,
'password': pwd,
'currentMenu': '1',
'execution': 'e1s1',
'_eventId': 'submit',
'geolocation': '',
'submit': '稍等片刻……'
}

# 获取CAS系统SESSION
# 这一步是必须的 要获取cookie
s.get(login_url, headers=headers)
# 登录
s.post(login_url, headers=headers, data=data)
# 这一步貌似并不是必要的 通过post提交一个数据
s.post(be_student_url, headers=headers, data={'actionType': 'getRoles'})
# 这一步是获得姓名信息
name_info = s.get(get_name_url, headers=headers).text
name = re.search(r'姓名:(.*)<', name_info).group(1)
# 获得查询参数 这是之前没有的
query_info = s.get(get_query_url, headers=headers).text
info = re.search(r'sign=(.*?)&timeStamp=(\d*)', query_info)
# 查询参数
sign = info.group(1)
timestamp = info.group(2)
# post请求提交 注意,url后面的参数可以忽略
post_url = 'http://yqtb.nwpu.edu.cn/wx/ry/ry_util.jsp?' + info.group()
params = {
'sign': sign,
'timeStamp': timestamp
}
data = {
'hsjc': '1',
'xasymt': '1',
'actionType': 'addRbxx',
'userLoginId': sno,
'szcsbm': '1',
'bdzt': '1',
'szcsmc': '在学校',
'sfyzz': '0',
'sfqz': '0',
'tbly': 'sso',
'qtqksm': '',
'ycqksm': '',
'userType': '2',
'userName': name,
}
# 这里要加一下请求源 必要
headers.update({
'Referer': 'http://yqtb.nwpu.edu.cn/wx/ry/jrsb.jsp',
'Origin': 'http://yqtb.nwpu.edu.cn',
})
r = s.post(post_url, headers=headers, data=data, params=params)
r = json.loads(r.text)
if r['state'] == "1":
print('成功')


if __name__ == '__main__':
sno = input('输入你的学号')
pwd = input('输入你的密码')
login(sno,pwd)

学习资料

JS逆向破解_哔哩哔哩_bilibili

这是偶然看到的,感觉挺不错,无聊时可以看看

-------------本文结束感谢您的阅读-------------
感谢阅读.

欢迎关注我的其它发布渠道