前言
完整源码如因环境问题无法运行(没有安装node环境),将解密部分换成python(已在博客中附上)即可。
分析
百度指数,发送数据的时候没有加密参数,直接将关键字替换就可以实现不同网页的访问,响应数据url:
https://index.baidu.com/api/SearchApi/index?word=王者荣耀&area=0&days=30
但是其响应的数据却有加密,所以我们要分析,如何对数据进行解密。
查看响应体
不难猜出,几个data为对应的数据实体。
找到加密的代码块
直接charles搜索userIndexes(太卡了就不放charles截图了)。可以看到all,pc,wise等关键字,很容易猜到这就是了。点击进入decrypt函数,很短的代码,我们只需要在这里打断点查看传入的数据与返回的数据即可。
经过调试发现t参数为动态变化的,而且其 是以n.data.data传入的,猜想可能是动态请求的,搜索一下,发现的确是请求过来的(电脑太卡了,有兴趣的小伙伴可以尝试一下)。请求参数uniqid为数据页返回的uniqid。
现在我们已经可以获取到加密数据与解密参数了,直接运行解密即可
说实话,这个解密过程很简单,完全可以写成python。
python实现解密过程
def decrypt(t:str,e:str) -> str:
n, i = t, e
a = {}
o = 0
r = []
while o < len(n) /2:
a[n[o]] = n[len(n)//2 + o]
o += 1
for s in range(len(e)):
r.append(a[i[s]])
return "".join(r)
完整代码
# -*- coding: utf-8 -*-
# @Time : 2019/7/24 15:36
# @Author : Conderfly
# @Email : coderflying@163.com
# @File : constants.py
js = '''function decrypt(t, e) {
for (var n = t.split(""), i = e.split(""), a = {}, r = [], o = 0; o < n.length / 2; o++) a[n[o]] = n[n.length / 2 + o];
for (var s = 0; s < e.length; s++) r.push(a[i[s]]);
return r.join("")
}'''
headers = {
"Cookie": "自己登陆后获取",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
}
data_url = 'https://index.baidu.com/api/SearchApi/index?word={}&area=0&days=30'
uniqid_url = 'https://index.baidu.com/Interface/ptbk?uniqid={}'
if __name__ == '__main__':
pass
# -*- coding: utf-8 -*-
# @Time : 2019/7/24 15:32
# @Author : Conderfly
# @Email : coderflying@163.com
# @File : baiduzhishu.py
import requests
import execjs
from constants import headers,js,data_url,uniqid_url
keys = ["all","pc","wise"]
class BaiDuIndex(object):
def __init__(self):
self.js_handler = self.get_js_handler()
self.session = self.get_session()
def decrypt(self, key, data):
# 若因环境问题无法运行,替换此方法即可
return self.js_handler.call('decrypt', key, data)
def do_request(self,url):
return self.session.get(url)
def parse(self,response,uniqid):
result = []
data_dict = response.get("data").get("userIndexes")[0]
for key in keys:
result.append({key:self.decrypt(uniqid,data_dict.get(key).get("data"))})
return result
def get_baidu_index(self,keyword):
response = self.do_request(data_url.format(keyword)).json()
uniqid = self.do_request(uniqid_url.format(response.get("data").get("uniqid"))).json().get("data")
return self.parse(response,uniqid)
@staticmethod
def get_js_handler():
return execjs.compile(js)
@staticmethod
def get_session():
session = requests.session()
session.headers =headers
session.verify = False
return session
if __name__ == '__main__':
baidu = BaiDuIndex()
print(baidu.get_baidu_index("王者荣耀"))