- 中国空气质量在线监测分析平台是一个收录全国各大城市天气数据的网站,包括温度、湿度、PM 2.5、AQI 等数据,链接为:https://www.aqistudy.cn/html/city_detail.html,网站显示为:
1 判断是否是动态加载
1 当搜索不同的数据时,发现网页地址没有发生变化======》》判断出是动态加载
2 通过抓包工具得出是ajax局部刷新加载
3 发现发送post请求传递的参数加密,响应数据也是加密的
4 需要对请求参数和响应数据经行解密
点击进去,发现有三个事件
找到getData()的定义
getWeatherData()的实现内部取查找相关的蛛丝马迹:定义了method='GETDETAIL'和param这两个变量,并且param是一个字典,字典中有四个键值对(city,type,startTime,endTime).还发现了另一个函数的调用getServerData(method,param,回调函数,0.5).
再谷歌浏览器进行全局搜索getServerData
发现找出的是经过加密的js函数的实现.
6 js代码块加密成为js混淆:我们必须将混淆的数据进行js反混淆.
js反混淆:通过该网站进行反混淆的操作http://www.bm8.com.cn/jsConfusion/
将加密数据复制到这个网站中进行解密
找到了动态请求参数值的来源:getParam(method, object);返回的就是我们苦苦寻找的动态变化的post请求参数.
找到了对ajax请求到的密文数据进行解密的js函数:decodeData(data),该函数参数data就是加密的响应数据,该函数的返回值就是经过解密的原文数据.
问题:找到的相关重要的信息对应的函数都是js写的,爬虫程序必须基于python实现.
.PyExecJS介绍:PyExecJS 是一个可以使用 Python 来模拟运行 JavaScript 的库。我们需要pip install PyExecJS对其进行环境安装。
如果想在python中使用PyExecJS必须实现安装好nodejs的环境
将网站解密代码代码放在一个js文件中,末尾加入
function getPostParamCode(method, city, type, startTime, endTime){
var param = {};
param.city = city;
param.type = type;
param.startTime = startTime;
param.endTime = endTime;
return getParam(method, param); //调用这个函数来解密
}
知识兔7 最后写python代码
import execjs
import requests
node = execjs.get()
# Params
method = 'GETDETAIL'
city = '北京'
type = 'HOUR'
start_time = '2018-01-25 00:00:00'
end_time = '2018-01-25 23:00:00'
# Compile javascript
file = 'js.js'
ctx = node.compile(open(file, encoding='utf-8').read())
# Get params
js = 'getPostParamCode("{0}", "{1}", "{2}", "{3}", "{4}")'.format(method, city, type, start_time, end_time)
params = ctx.eval(js)
print(params)
url = 'https://www.aqistudy.cn/apinew/aqistudyapi.php'
pm = {
'd':params
}
#text就是请求到的加密的响应数据
text = requests.post(url,data=pm).text
js = 'decodeData("{0}")'.format(text)
data = ctx.eval(js)
print(data)
知识兔View Code