抓取异步数据


一.异步加载:

让静态部分先以同步的方式装载,然后动态的部分向服务端发送一个或多个异步请求,从服务端接收到数据后,再将数据显示在页面上。这种技术就是AJAX,英文全称是
Asynchronous JavaScript and XML,中文可以称为"异步JavaScript和XML"。
AJAX有两层含义:一层含义是异步(Asynchronous),这是指请求和下载数据的方式是异步的,也就是不占用主线程,即使加载数据缓慢,也不会出现页面卡顿的现象,顶多是内容没有显示出来(可以用默认数据填充);另一层含义是指传输数据的格式,AJAX刚出现时,人们习惯使用XML格式进行数据传输,但现在不会了,XML格式会出现很多数据冗余,目前经常使用的数据传输格式是JSON,不过由于AJAX的名字已经广为人知,所以一直沿用。

二.AJAX的基本原理

AJAX的实现分为3步:发送请求(通常是指HTTP请求)、解析响应(通常是指JSON格式的数据)和渲染页面(通常是指将JSON格式的数据显示在Web页面的某些元素上)

2.1发送请求

Javascript本身并没有发送HTTP请求的API,需要调用浏览器提供的API,不过不同浏览器发送HTTP请求的API不同,如IE7+版本以上的浏览器,需要使用XMLHttpRequest对象发送请求,而IE7以下版本的浏览器,需要使用下面的代码创建Microsoft.XMLHTTP对象。

xmlhttp = new ActiveXObject('Microsoft.XMLHTTP')

所以在发送请求时需要考虑到浏览器的兼容性,建议使用jQuery发送请求,因为jQuery已经考虑到了不同浏览器平台的差异性。
jQuery下载地址https://jquery.com/download
在html页面种引用jquery.js文件


然后可以使用下面的代码向服务端发送请求

$.get("/service",function()result{
      console.log(result)
});

发送请求是异步的,所以需要通过get函数的第2个参数指定回调函数,一旦服务端返回响应数据,可以通过回调函数的参数(本例是result)获取响应数据。通常在这个回调函数中利用服务端返回的数据渲染页面。

2.2解析响应

这里的响应数据主要指的是JSON格式的数据。可以使用下面的代码将字符串形式的数据转换为Javascript对象形式的JSON数据。其中result是get函数的回调函数的参数。得到JavaScript对象形式的JSON数据,就可以任意访问数据了.

JSON.parse(result)

2.3渲染页面

渲染页面主要是指将从服务端获取的响应数据以某种形式显示在Web页面的某些元素上。如下面的代码将数据以

  • 节点的形式添加到
      节点的后面

      $('#video_list').append('
    • + data[i].name + '
    • ')

      video_list是

        节点的id属性值,data是JSON对象。append函数用于将HTML代码追加到video_list指定节点的内部HTML代码的最后

        2.3.1使用Flask实现Web服务(运行显示的是无法打开页面;要用localhost:1234这个url打开,而0.0.0.0:1234这个url打不开)

        
        from flask import Flask,render_template
        from flask import make_response
        import json
        app = Flask(__name__)
        # 根路由,用于显示index.html页面
        @app.route('/')
        def index():
            return render_template('index.html')
        # 响应客户端请求的路由
        @app.route('/data')
        def data():
            # 定义要返回的数据(包含4个字典的列表)
            data = [
                {'id':1,'name':'PyQt5(Python)实战视频课程'},
                {'id':2,'name':'Electron实战'},
                {'id':3, 'name': '征服C++ 11'},
                {'id':4, 'name': '征服Flask'},
        
            ]
            # 将json列表转化为json格式的字符串,然后创建响应对象
            response = make_response(json.dumps(data))
            # 返回响应对象
            return response
        
        
        if __name__ == '__main__':
            app.run(host = '0.0.0.0',port=1234)
        

        三.逆向工程

        如果数据没有在Response选项卡中,那么很可能是通过异步方式获取的数据,然后再利用JavaScript将数据显示在页面上。
        因为目前显示数据的方式只有两种:同步和异步。
        其中在Elements选项卡中,XHR捕获的是异步数据,XHR是XMLHttpRequest的缩写,但注意,XHR过滤的URL与返回数据的格式无关,只与发送请求的方式有关,XHR用于过滤异步方式发送的请求。
        本例展示抓取异步访问的URL,并将返回数据转换为Python字典,最后输出返回的所有视频课程名称

        import requests
        import json
        from lxml import etree
        result = requests.get('http://localhost:1234/data')
        # 由于返回的数据包含中文(unicode编码),所以需要将其编码
        text = result.text.encode('utf-8').decode('unicode-escape')
        
        print(text)
        # 将字符串形式的json转化为Python字典
        data = json.loads(text)
        print('个数:',len(data))
        # 输出返回所有的内容
        for value in data:
            print(value['name'])