点击时候确定某个元素 js_某空气质量监测平台 JS反爬

本文详细介绍了如何分析中国空气质量在线监测分析平台的Ajax请求,通过Chrome开发者工具定位到加密和解密方法,使用在线反混淆工具还原JavaScript代码,并利用Python的PyExecJS库模拟执行加密和解密过程,从而获取并解析城市空气质量数据。
摘要由CSDN通过智能技术生成

99b741bb030d6d121019bfc4bf67168b.png

目标:中国空气质量在线监测分析平台|城市分析 参考CSDN中文章,记录一下学习过程

a6a5df0bcf58655fcf2f66ef9abf554f.png

通过切换城市,页面数据是通过 Ajax 加载的,数据接口:https://www.aqistudy.cn/apinew/aqistudyapi.php

请求的POST Data、返回的数据都被加密了

c3892c4cf189762ace03289243220b8e.png

d0c5df115cc44f96c13754d37c09c65e.png

分析网站接口的加密逻辑

js加密的一般处理思路:

  • 加密url或某个post data参数时,可以全局搜索对应的参数名或者值,确定js函数
  • 整个post data加密或无法搜索到参数,可通过元素的事件监听,确定js函数

1. 这里搜索参数名 d 显然不现实,当我们点击切换城市或者搜索按钮之后,后台便会发出 Ajax 请求,说明这个点击动作是被监听的,所以我们可以找一下这个点击事件对应的处理代码在哪里,这里可以借助于 Firefox 来实现,它可以分析页面某个元素的绑定事件以及定位到具体的代码在哪一行

切换城市or点击搜索

1c102ba0c3adf0ec0eb264be65e9e971.png

e401c10ffb7774fbf2fd347f4a80bb5d.png

2.发现绑定的 click 事件调用了 getData() 函数,显然是获取数据的js,搜索这个函数

1899c4031be425a285c5be8e2595b241.png

在 city_detail.html 的第 463 行就找到了这个函数的声明

a4c1172c74bf759b97b485c6107a3e1a.png

3.发现它又调用了 getAQIData() 和 getWeatherData() ,这两个方法的声明就紧挨在下面,再进一步分析发现这两个方法都调用了 getServerData() 这个方法,并传递了参数 method、param ,还有一个回调函数很明显是对返回数据进行处理的,这说明 Ajax 请求就是由这个 getServerData() 方法发起的,如图所示:

0002592d5b21a3adb844703065cd888f.png

4.继续搜索这个函数 getServerData()

536f521a89d3a44888b3b4991e024418.png

city_detail.html 中的是上面两个方法调用了 getServerData() ,这个文件里面并没有getServerData() 的声明

貌似在 https://www.aqistudy.cn/js/jquery-1.8.0.min.js?v=1.2 中 右键 选择在Sources中打开,继续搜

1f49361212ca6e11a43a7f74c6dfeedd.png

果然找到了,发现这里经过 JavaScript 混淆加密了,这个方法名后面怎么直接跟了一些奇怪的字符串,而且不符合一般的 JavaScript 写法,而且这行代码的开头为eval(function(p,a,c,k,e,d)这种形式。

5.利用在线反混淆网站(http://www.bm8.com.cn/jsConfusion/)将 jquery-1.8.0.min.js 中这行 eval 开头的混淆后的 JavaScript 代码复制一下,然后粘贴到这个网站中进行反混淆,就可以看到正常的 JavaScript 代码了,搜索一下就可以找到 getServerData() 方法了,可以看到这个方法确实发出了一个 Ajax 请求,请求了Ajax 加载的数据接口:

1e06414b3c7b12c5ce3616de304fff90.png

在这里发现了一个getParam()方法:它接受了 method 和 object 参数,然后返回得到的 param 结果就作为加密后的 POST Data,也就是d:后面的那一堆字符串

这里面还有一个decodeData()方法:对服务器传回的数据进行解密

6.还是在这一堆反混淆代码中,紧挨着上面代码找到了getParam()和decodeData()

cf2f2dc3bc9d10a7ace6b640ddb8b691.png

其中 POST Data 的加密过程是 Base64 + AES 加密,Response Data 的解密是 AES + DES + Base64 解密

代码

PyExecJS 是一个可以使用 Python 来模拟运行 JavaScript 的库

pip install PyExecJS

还需安装JS运行环境(推荐安装 Node.js )

Go~

不需要用 Python 重写一遍 JavaScript,直接用 Python 来模拟运行 JavaScript 就好

将刚才反混淆的 JavaScript 保存成一个文件,叫做 encryption.js,然后用 PyExecJS 模拟运行相关的方法即可。

首先我们来实现加密过程,这里 getServerData() 方法其实已经帮我们实现好了,并实现了 Ajax 请求,但这个方法里面有获取 Storage 的方法,Node.js 不适用,所以这里不用它也别管他, 添加一个 getEncryptedData() 方法实现加密,在 encryption.js 最后面加入一段代码,实现如下方法:

function getEncryptedData(method, city, type, startTime, endTime) {
    var param = {};
    param.city = city;
    param.type = type;
    param.startTime = startTime;
    param.endTime = endTime;
    return getParam(method, param);
}

用于传递数据,调用参数加密函数

接下来用python模拟执行这些方法即可:

import execjs
import json
import requests

# Init environment
# 通过 execjs(即 PyExecJS)的 get() 方法声明一个运行环境
node = execjs.get()

# Params
# 换成'GETCITYWEATHER'获取温度,风向等数据
method = 'GETDETAIL' 
city = '重庆'
type = 'HOUR'
start_time = '2019-09-06 00:00:00'
end_time = '2019-09-06 12:00:00'

# Compile javascript
file = 'encryption.js'
# 调用 compile() 方法来执行刚才保存下来的加密库 encryption.js,执行一遍才能调用
with open(file, encoding=('utf-8')) as f:
    ctx = node.compile(f.read())

# Get params
# 调用一下 JavaScript 中的 getEncryptedData() 方法即可实现加密
# 通过 eval() 方法来模拟执行,得到的结果赋值为 params,这个就是 POST Data 的加密数据
js = 'getEncryptedData("{0}", "{1}", "{2}", "{3}", "{4}")'.format(method, city, type, start_time, end_time)
params = ctx.eval(js)

# Get encrypted response text
url = 'https://www.aqistudy.cn/apinew/aqistudyapi.php'
response = requests.post(url, data={'d': params})

# Decode data
# 调用一下 JavaScript 中的 decodeData() 方法即可实现解密
js = 'decodeData("{0}")'.format(response.text)
decrypted_data = ctx.eval(js)

data = json.loads(decrypted_data)
res = data.get('result').get('data').get('rows')
for i in res:
    print(i)

method = 'GETDETAIL' 可以获得aqi(空气质量指数),pm2.5 等数据

bff2963ac718d318ca035d25f73a3320.png

换成'GETCITYWEATHER' 可以获取温度,风向等数据

64a21cf8f7b8755d5d55c79bf5958b46.png

Github:https://github.com/Ingram7/AQI

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值