猿人学 — 第1届第3题
-
翻页发现一共有两个请求
-
第一个请求:返回状态码为
202
(服务器已经接收请求,但尚未处理),响应头中还有一个Set-Cookie
-
第二个请求:返回了我们想要的数据,携带的Payload中也只有一个表示页数的参数
m
,不过携带的Cookie中有上一步返回的sessionid
。因此猜想,若想获得页面中的数据,必须先发送第一个jssm的请求,获得返回的sessionid
后再发送第二个请求
-
-
考虑到第一个请求返回的状态码为202,并且第二个请求建立在第一个请求基础上,因此采用
requests
模块中的requests.session()
会话对象进行请求- 尝试1:请求头中设置了
User-Agent
,Referer
,Origin
,Cookie
几个常见参数,发现请求返回数据不对 - 尝试2:按照Chrome中Headers,将所有请求头参数补充上,发现请求返回数据还是不对
- 尝试1:请求头中设置了
-
这就很奇怪了,第一步
sessionid
也获取了,为什么还是不行呢?打开Fiddler,看一下翻页发送的请求的具体情况。发现在请求的原始数据中,请求头中的参数与Chrome中是一致的,唯一不一样的是各个参数的顺序,难道是服务器检测了请求头的顺序?
- 尝试3:按照Filler中
https//match.yuanrenxue.cn/api/match/3?page=3
请求的原始数据重新排列请求头中的参数,还是发现请求返回数据不对 - 尝试4:按照Filler中
https//match.yuanrenxue.cn/jssm
请求的原始数据重新排列请求头中的参数,终于获得了目标数据 - 尝试5:在尝试4成功的基础上,修改请求头中一些参数的顺序,发现有时可以获得目标数据有时则不能
- 尝试3:按照Filler中
-
猜测:服务器很可能是对请求头中某几个参数的相对位置进行了检测,仅为个人猜测,还请大佬们批评指正,不吝赐教。源码如下
import requests # 创建会话,请求头完全按照Fiddler抓包jssm请求原始数据中的情况排列 obj = requests.session() obj.headers = { 'Host': 'match.yuanrenxue.cn', 'Connection': 'keep-alive', 'Content-Length': '0', 'Pragma': 'no-cache', 'Cache-Control': 'no-cache', 'sec-ch-ua-platform': '"Windows"', 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36', 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', 'sec-ch-ua-mobile': '?0', 'Accept': '*/*', 'Origin': 'https://match.yuanrenxue.cn', 'Sec-Fetch-Site': 'same-origin', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Dest': 'empty', 'Referer': 'https://match.yuanrenxue.cn/match/3', 'Accept-Encoding': 'gzip, deflate, br, zstd', 'Accept-Language': 'zh-CN,zh;q=0.9', # Cookie中的sessionid设置成你自己的 'Cookie': 'Hm_lvt_c99546cf032aaa5a679230de9a95c7db=1728573597; HMACCOUNT=5A088C25C5CFA391; qpfccr=true; no-alert3=true; Hm_lvt_9bcbda9cbf86757998a2339a0437208e=1728573661; tk=8258780053392544352; sessionid=78sqn10uftr6obdv5xb79bah299trkb8; Hm_lpvt_9bcbda9cbf86757998a2339a0437208e=1728573869; Hm_lpvt_c99546cf032aaa5a679230de9a95c7db=1728574043' } value_dict = {} for pid in range(1,6): obj.post(url='https://match.yuanrenxue.cn/jssm') res = obj.get(url=f'https://match.yuanrenxue.cn/api/match/3?page={pid}') data = res.json()['data'] print(data) for item in data: count = value_dict.get(item['value'],0) value_dict[item['value']] = count + 1 value_list = [(key,value) for key,value in value_dict.items()] value_list.sort(key=lambda x:int(x[1]),reverse=True) print(value_list) print(f"出现最多的申请号是{value_list[0][0]},出现的次数是{value_list[0][1]}次")
-
运行结果