在正常情况下,对于需要登录的网站,一般只要将登录后的cookie携带到headers中就可以实现认证后的访问请求。但是,也有例外。
最近,州的先生(zmister.com)遇到了一个网站,就是那样的例外。
请求受阻
通过页面调试,找到了其数据接口,如下图所示:
数据在接口的响应中一览无遗,于是按照常例,我们马上构造一个与网页请求一样的headers:
然后使用requests对接口url进行请求:
response = requests.get(url, headers=headers, timeout=5)
print(response.text)
本以为会顺顺利利地看到接口数据被打印出来,没想到返回的却是一个401的响应,内容为:
Illegal access
显然,它提示我们未授权访问。但是我们明明已经将登陆后的Cookie放到了headers中。如果cookie没问题,那么就要分析其他的地方了。
分析JS
排查一番,发现请求参数是没问题的,header里面的compassS是一个会变化的值,问题应该就出在这里。
为了验证这个猜想,我们在调试控制台中搜索包含compassS的文件资源,搜出来一个js文件:
将其复制出来进行格式化,继续搜索compassS字符串,发现了这个header的来源函数:
compassS的值为变量u,其结构为下所示:
'1553669366913_95857b7e16509a775b3e62b8e5fd0944',
可以看到变量u是由以下两个个部分组成:
- 当前时间的时间戳;
- 查询字符串、固定字符串和当前时间时间戳的MD5加密字符串的切片;
构造加密字符串
了解了这些,我们就可以来构造headers里面的compassS键了,代码如下所示:
timer = int(round(time.time() * 1000))
m = hashlib.md5()
s = 'getDetailsComPASs#123&WEb{}'.format(timer)
m.update(bytes(s,encoding='utf-8'))
l = m.hexdigest()
ll = l[6:len(l)] + l[0:6]
其中,timer是前半部分的时间戳,ll是后半部分的MD5加密字符串,我们将其拼接起来:
'compassS': '{0}_{1}'.format(timer,ll),
再次进行请求,可以发现,请求已经成功返回了正确地数据,如下图所示:
这样,我们就通过对加密请求头进行解密解决了接口请求限制的问题。
欢迎留言讨论~
文章版权所有:州的先生博客,转载必须保留出处及原文链接