• 该请求是一个ajax请求,查看ajax请求对应的js代码或者Jquery代码中有没有请求参数的设置呢?
  • 当点击了页面中的查询按钮后,就会发起一个ajax请求。说明该查询按钮一定被绑定了一个点击事件,当点击事件发生后就会执行一组ajax请求的代码。
  • 通过查看ajax请求代码,就可以发现请求参数的参数值。
  • 示例代码:

    $.ajax({
           	 url:"发送请求(提交或读取数据)的地址", 
             dataType:"预期服务器返回数据的类型",  
             type:"请求方式", 
             async:"true/false",
             data:{id:func},
             success:function(data){请求成功时执行},      
             error:function(){请求失败时执行}
    

    4.寻找ajax请求的代码。

  • 找到查询按钮绑定的点击事件。(火狐浏览器的开发者工具)

    5.发现getData函数就是点击了查询按钮后触发的函数,该函数实现内容去查询ajax请求的代码

    6.查看getData函数的实现:

    跳转到指定的位置

    局部搜索getData

    type=="HOUR":查询条件是以小时为单位

    没有发现ajax请求代码,但有另外的两个函数的调用,

    说明ajax请求代码一定是存在于这两个函数实现中。

    getAQIData();

    getWeatherData();

    7.查看getAQIData的实现:

  • 未发现ajax请求代码,发现了另一个函数调用getServerData,
  • getServerData参数:
  • method = GETDETAIL
  • param =
  • function getServerData(method, object, callback, period) {
            const key = hex_md5(method + JSON.stringify(object));
            const data = getDataFromLocalStorage(key, period);
            if (!data) {
                var param = getParam(method, object);
                $.ajax({
                    url: '../apinew/aqistudyapi.php',
                    data: {
                        d: param
                    type: "post",
                    success: function (data) {
                        data = decodeData(data);
                        obj = JSON.parse(data);
                        if (obj.success) {
                            if (period > 0) {
                                obj.result.time = new Date().getTime();
                                localStorageUtil.save(key, obj.result)
                            callback(obj.result)
                        } else {
                            console.log(obj.errcode, obj.errmsg)
            } else {
                callback(data)
    

    3、js逆向获取数据:

  • 可以将js代码改写成python代码进行相关的调用。
  • 1.手动将js函数改写成python函数
  • 2.可以使用工具自动进行python函数的改写
  • pyexclJS
  • 将解密成功的js方法存放到本地jsCode.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);
    
    #动态实时获取ajax请求的参数
    import execjs
    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 = 'jsCode.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)
    tdgHOYxwKdDSgYXe+RLPzYCgLvrddahasI5XXklB4gVLYqab+XRPpMD/oSqnJ/aEmFwzVEUhLnPzRy03+X1BIzLvxQKwu4A3YsqR3OemYgNnHqPdBwvJlbxia99YeK+xNLwdqFad2OO8kQ/eMmdXDnGMvVAdhy3hOdXSgMgwVdUjXSyKzDV31TAxmYlJqwB6U3oElEpwW7AG1sOS1EpGER7Q1a1xkekm9tvDAeHRXrPB1jXX4hsdnZoYBSE23ei+sBC/30MZXDD1ons7hnF4fNS7j0aSqyscRk5ueQAvN1FRHCg9aM9tClVrDd4dC9q5Tk8vlH8aiTmGBZjYRkdIina1REOBdr3z73I+8GTRintq9RjSTycygKb3IpNejPAtU+P4FwPOmhiTCf1pDl0GXOw23BHL/8yR0yWCSHwOH+EDUmV+oQKOwh7T84w7LGjaHB0hGrvW94R6bI5iC+Qsaw==
    
    #携带上动态变化的请求参数发起ajax请求获取加密的响应数据
    import execjs
    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 = 'jsCode.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)			#调用执行封装好的方法
    #发起post请求
    url = 'https://www.aqistudy.cn/apinew/aqistudyapi.php'
    response_text = requests.post(url, data={'d': params}).text
    print(response_text)
    qZMXM1uw6YvIv1UWRplJEP8adQ/jrupTMOgOGHddu9sLczXIVdbUQNC6FKKO1n/E+u+ROZbS20IkqL9BxAlZGzas1Cr/5Xra0/8RJ4dgOSerFidYiI6gQTe2hR83SC2FtPOuHYS/0KmslfuTqyH21g==
    
    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 = 'jsCode.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)
    #发起post请求
    url = 'https://www.aqistudy.cn/apinew/aqistudyapi.php'
    response_text = requests.post(url, data={'d': params}).text
    #对加密的响应数据进行解密
    js = 'decodeData("{0}")'.format(response_text)
    decrypted_data = ctx.eval(js)
    print(decrypted_data)
    

    这篇博文涉及到的反爬机制有:

  • js逆向可以破解js加密
  • 动态变化的请求参数
  •