每日一语:只要充分相信自己,没有什么困难可以足够持久。
前言:
前段时间因为河南省教育厅发了一个国家安全知识网页答题,然后我的好学长(手动滑稽)就带我做了一个答题脚本,也是非常感谢学长给的这次机会让我接触这么好玩的东西(滑稽)。虽然我有点笨,这么简单的一个东西做了好几天,但是最终做出来还是有很大的收获的嘿嘿嘿嘿。
(不要问我为啥答题结束才发脚本,因为我怕吃国家饭(手动滑稽))
上图是学长给的核心思路嘿嘿嘿嘿,让我明白这个脚本的好玩之处嘿嘿嘿!!!!
目录
脚本原理
网页抓包
分析包
发送请求
脚本代码
1、答题代码
2、学校编号获取代码(这个只完成了部分,缺少最后的清洗数据):
展示
总结
脚本原理
网页抓包
网页抓包是这个脚本的第一个步骤,也是开启的脚本不可或缺的步骤。
我们打开答题网页:
我开始一般抓包都是用f12查看网页源码,但是这个网页我第一次使用f12的时候既然出不来网页源码,当场让我吃闭门羹,最后我写完后换了一个方法查看源码的时候却发现这个网页的开发者把f12这个功能关闭了,估计就是怕有一些帅哥写脚本答题(没错就是我嘿嘿嘿嘿),
然后我在学长的指引下我用了 Fiddler 来抓包,这个也让我打开了新世界,这个不仅能很好的解决f12 打不开的问题,还能解决一些抓包丢失的问题,所以我还是很推荐这个软件抓包的。
这个是我在上数据结构实验课时在老师旁边的时候抓的嘿嘿嘿,第一次抓有些没抓好,最后还是学长给我说抓哪些包呜呜呜呜。
这些就是抓的核心包,接下来我们呢对他们进行分析。
分析包
1、首先对 islogin进行分析:
url = 'http://gjaqzsjs.haedu.cn/Login/isLogin'
headers = {'Host': 'gjaqzsjs.haedu.cn', 'Connection': 'keep-alive', 'Content-Length': '0', 'Accept': '*/*',
'Origin': 'http://gjaqzsjs.haedu.cn', 'X-Requested-With': 'XMLHttpRequest',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
'Referer': 'http://gjaqzsjs.haedu.cn/', 'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9'}
我们需要获取isLogin的一些请求头的参数。
然后获取变化的cookie(因为这个是每次都会变化的,而且后面的每次请求都需要这个参数,所以我们对isLogin请求的目的就是获取动态的cookie参数)。
2、接下来我们就要对账号的登录进行分析:
url = 'http://gjaqzsjs.haedu.cn/Login/auth'
headers = {'Host': 'gjaqzsjs.haedu.cn', 'Connection': 'keep-alive', 'Content-Length': '48', 'Accept': '*/*',
'Origin': 'http://gjaqzsjs.haedu.cn', 'X-Requested-With': 'XMLHttpRequest',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Referer': 'http://gjaqzsjs.haedu.cn/', 'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9'}
cookies = {
'XSRF-TOKEN': cookieArr["XSRF_TOKEN"],
'laravel_session': cookieArr["laravel_session"]}
data = {
'unit_code': str(20),//这个数字是每个学校的编号,后面我们会对每个学校编号进行爬取
'student_id': str(userId),
'password': str(passwd)
}
上面的代码就是对登录请求的一些参数。
3、然后我们在找到getQuestion这个包,对其进行分析(其实这一步可以省略的):
url = 'http://gjaqzsjs.haedu.cn/Answer/getQuestionLists'
headers = {'Host': 'gjaqzsjs.haedu.cn', 'Connection': 'keep-alive', 'Content-Length': '0', 'Accept': '*/*',
'Origin': 'http://gjaqzsjs.haedu.cn', 'X-Requested-With': 'XMLHttpRequest', 'Access-Token': 'null',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
'Referer': 'http://gjaqzsjs.haedu.cn/gjaq_dati/page/answer.html', 'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9'}
cookies = {
'XSRF-TOKEN': cookieArr["XSRF_TOKEN"],
'laravel_session': cookieArr["laravel_session"]}
通过这个包我们可以获取当天所需答题对的内容(但是在本思路中其实并没有去用到这个,只是给大家简单的介绍了一下)。
4、接下来就是最核心的地方:
找到
submitAnswer这个包。
我们能看见这个有一个answer这个参数,而这个也就是这个脚本的核心!!!
我们一般正常人的思路都是获取题目然后找到相对应的答案提交,但是!!!!
在这个里面我们可以直接找一套满分的题目和答案然后通过answer这个参数发送个服务器,而服务器只是接受到你的答案是否正确,所以通过这点,我们可以写一个一秒满分的脚本!!
(这里声明一下,最开始我也是正常思维卡了半天,对亏学长指点了一下嘿嘿嘿)
5、最后一个包就是对服务器返回来的分数包进行分析和提取相对应的分数(当然都是满分啦)
也就是这个包的参数
和上面的分析相同,我就不废话了。
发送请求
发送请求也就是把我们弄好的参数和一些data对服务器进行发送,并接收服务器返回的信息。
我们通过包能分析到有些事post请求有些事get请求,我们可以分别用python的requests这个库里面的post和get两种请求对服务器进行请求。
例如:
html = requests.post(url, headers=headers, verify=False, cookies=cookies, data=data)
脚本代码
1、答题代码
import requests,re,json,datetime,random
answer = [{'number': '431', 'answer': 'D'}, {'number': '19', 'answer': 'B'}, {'number': '208', 'answer': 'D'}, {'number': '123', 'answer': 'C'}, {'number': '437', 'answer': 'B'}, {'number': '343', 'answer': 'D'}, {'number': '333', 'answer': 'B'}, {'number': '700', 'answer': 'ABCD'}, {'number': '692', 'answer': 'ABC'}, {'number': '582', 'answer': 'ABCD'}, {'number': '694', 'answer': 'ABCD'}, {'number': '625', 'answer': 'ACD'}, {'number': '648', 'answer': 'ABCD'}, {'number': '799', 'answer': 'B'}, {'number': '834', 'answer': 'B'}, {'number': '878', 'answer': 'B'}, {'number': '802', 'answer': 'A'}, {'number': '968', 'answer': 'B'}, {'number': '985', 'answer': 'A'}, {'number': '913', 'answer': 'B'}]
stuInfo = {}
cookieArr = {}
userInfo = {}
def regeditCookie():
global cookieArr
url = 'http://gjaqzsjs.haedu.cn/Login/isLogin'
headers = {'Host': 'gjaqzsjs.haedu.cn', 'Connection': 'keep-alive', 'Content-Length': '0', 'Accept': '*/*',
'Origin': 'http://gjaqzsjs.haedu.cn', 'X-Requested-With': 'XMLHttpRequest',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
'Referer': 'http://gjaqzsjs.haedu.cn/', 'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9'}
cookies = {}
data = {}
html = requests.post(url, headers=headers, verify=False, cookies=cookies, data=data)
XSRF_TOKEN = re.findall(r'XSRF-TOKEN=(.*?);', html.headers['Set-Cookie'], re.I)[0]
laravel_session = re.findall(r'laravel_session=(.*?);', html.headers['Set-Cookie'], re.I)[0]
cookieArr = {"XSRF_TOKEN":XSRF_TOKEN,"laravel_session":laravel_session}
def login(schoolId,userId,passwd):
regeditCookie()
global stuInfo,cookieArr,userInfo
# print(cookieArr)
url = 'http://gjaqzsjs.haedu.cn/Login/auth'
headers = {'Host': 'gjaqzsjs.haedu.cn', 'Connection': 'keep-alive', 'Content-Length': '48', 'Accept': '*/*',
'Origin': 'http://gjaqzsjs.haedu.cn', 'X-Requested-With': 'XMLHttpRequest',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Referer': 'http://gjaqzsjs.haedu.cn/', 'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9'}
cookies = {
'XSRF-TOKEN': cookieArr["XSRF_TOKEN"],
'laravel_session': cookieArr["laravel_session"]}
data = {
'unit_code': str(20),
'student_id': str(userId),
'password': str(passwd)
}
html = requests.post(url, headers=headers, verify=False, cookies=cookies, data=data)
print(html.text)
stuInfo = json.loads(html.text)
if stuInfo['code'] == 2000:
userInfo = stuInfo['data']
getQuestionLists()
submitAnswer(answer)
else:
print("登录失败!")
def getQuestionLists():
url = 'http://gjaqzsjs.haedu.cn/Answer/getQuestionLists'
headers = {'Host': 'gjaqzsjs.haedu.cn', 'Connection': 'keep-alive', 'Content-Length': '0', 'Accept': '*/*',
'Origin': 'http://gjaqzsjs.haedu.cn', 'X-Requested-With': 'XMLHttpRequest', 'Access-Token': 'null',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
'Referer': 'http://gjaqzsjs.haedu.cn/gjaq_dati/page/answer.html', 'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9'}
cookies = {
'XSRF-TOKEN': cookieArr["XSRF_TOKEN"],
'laravel_session': cookieArr["laravel_session"]}
html = requests.post(url, headers=headers, verify=False, cookies=cookies)
q = json.loads( html.text)
print(q)
if q["code"] == 4400:
print("今天已经答过题了!!!")
elif q["code"] == 2000:
data = q["data"]
def submitAnswer(answer):
url = 'http://gjaqzsjs.haedu.cn/Answer/submitAnswer'
headers = {'Host': 'gjaqzsjs.haedu.cn', 'Connection': 'keep-alive', 'Content-Length': '0', 'Accept': '*/*',
'Origin': 'http://gjaqzsjs.haedu.cn', 'X-Requested-With': 'XMLHttpRequest', 'Access-Token': 'null',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
'Referer': 'http://gjaqzsjs.haedu.cn/gjaq_dati/page/answer.html', 'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9'}
cookies = {
'XSRF-TOKEN': cookieArr["XSRF_TOKEN"],
'laravel_session': cookieArr["laravel_session"]}
data = {
"answer" : str(answer).replace("\'","\""),
"use_time": f'{random.randint(300, 450)}'
}
html = requests.post(url, headers=headers, verify=False, cookies=cookies, data=data)
q = json.loads(html.text)
# print(q)
if q["code"] == 4600:
print("提交成功!")
socore()
else:
print("提交失败!")
print(q["code"])
def socore():
global cookieArr,jsonData
url = 'http://gjaqzsjs.haedu.cn//Answer/getRecord'
headers = {'Host': 'gjaqzsjs.haedu.cn', 'Connection': 'keep-alive', 'Content-Length': '13', 'Accept': '*/*',
'Origin': 'http://gjaqzsjs.haedu.cn', 'X-Requested-With': 'XMLHttpRequest', 'Access-Token': 'null',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Referer': 'http://gjaqzsjs.haedu.cn/gjaq_dati/page/record.html?date=20211201',
'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9'}
cookies = {
'XSRF-TOKEN': cookieArr["XSRF_TOKEN"],
'laravel_session': cookieArr["laravel_session"]}
data = {
'date': str(datetime.datetime.now().strftime('%Y%m%d'))
}
html = requests.post(url, headers=headers, verify=False, cookies=cookies, data=data)
jsonData = json.loads(html.text)
print("最后分数为:",jsonData["data"]['score'])
school = input("请输入学校:")
sno = input("请输入学号:")
passwd = input("请输入密码:")
login(school,sno,passwd)
2、学校编号获取代码(这个只完成了部分,缺少最后的清洗数据):
import requests
import json
url = 'https://haedu-2021.oss-cn-beijing.aliyuncs.com/gjaqzsjs/competition/unit.json'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.43'
}
reponse = requests.get(url,headers = headers)
# print(reponse.text.replace(',',''))
school_dict = reponse.text.replace('[','{')
d1 = school_dict.replace("]",'}')
# d2 = d1.replace(']','}')
# print(school_dict)
# q = json.loads(d1)
# print(q)
print(d1)
展示
总结
最后也是很感谢学长带我写这次的答题脚本,因为第一次接触这个东西,有很多地方不是很懂,学长也给出了指点。三鞠躬(手动狗头嘿嘿嘿)。
大家可以按照这个脚本的思路去写一些其他的网页答题脚本哦,还是要提醒大家不要用做非法途径哦,最后也祝大家生活愉快,快快乐乐。