• Python爬虫技术系列-03/4flask结合requests测试静态页面和动态页面抓取


    python构建web服务

    flask内容参考:Flask框架入门教程(非常详细)

    flask安装与运行测试

    安装flask

    pip install flask
    
    • 1

    创建一个webapp.py文件,内容如下

    from flask import Flask
    
    # 用当前脚本名称实例化Flask对象,方便flask从该脚本文件中获取需要的内容
    app = Flask(__name__)
    
    #程序实例需要知道每个url请求所对应的运行代码是谁。
    #所以程序中必须要创建一个url请求地址到python运行函数的一个映射。
    #处理url和视图函数之间的关系的程序就是"路由",在Flask中,路由是通过@app.route装饰器(以@开头)来表示的
    @app.route("/")
    #url映射的函数,要传参则在上述route(路由)中添加参数申明
    def index():
        return "Hello World!"
    
    # 直属的第一个作为视图函数被绑定,第二个就是普通函数
    # 路由与视图函数需要一一对应
    # def not():
    #     return "Not Hello World!"
    
    # 启动一个本地开发服务器,激活该网页
    app.run()
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    运行代码

     python webapp.py
    
    • 1

    终端输出如下:

    & D:/ProgramData/Anaconda3/envs/py10/python.exe d:/zjdemo/webapp.py
     * Serving Flask app 'webapp'
     * Debug mode: off
    WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
     * Running on http://127.0.0.1:5000
    Press CTRL+C to quit
    127.0.0.1 - - [20/Nov/2023 08:20:47] "GET / HTTP/1.1" 200 -     
    127.0.0.1 - - [20/Nov/2023 08:20:47] "GET /favicon.ico HTTP/1.1" 404 -
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在浏览器输入

    http://127.0.0.1:5000
    
    • 1

    返回如下
    在这里插入图片描述

    flask返回复杂的html字符串

    创建webapp_html_str.py文件,代码如下:

    from flask import Flask
    
    # 用当前脚本名称实例化Flask对象,方便flask从该脚本文件中获取需要的内容
    app = Flask(__name__)
    
    
    html_str="""
    
    
    
    
        
        
        Document
    
    
        
    th标头 th标头 地址
    td表格单元 td表格单元 上海浦东虹桥某某小区某某地点
    td表格单元 td表格单元 td表格单元
    td表格单元 td表格单元 td表格单元
    """
    #程序实例需要知道每个url请求所对应的运行代码是谁。 #所以程序中必须要创建一个url请求地址到python运行函数的一个映射。 #处理url和视图函数之间的关系的程序就是"路由",在Flask中,路由是通过@app.route装饰器(以@开头)来表示的 @app.route("/") #url映射的函数,要传参则在上述route(路由)中添加参数申明 def index(): return html_str # 直属的第一个作为视图函数被绑定,第二个就是普通函数 # 路由与视图函数需要一一对应 # def not(): # return "Not Hello World!" # 启动一个本地开发服务器,激活该网页 app.run()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    运行
    运行代码

     python webapp.py
    
    • 1

    在浏览器输入

    http://127.0.0.1:5000
    
    • 1

    返回如下
    在这里插入图片描述

    flask返回html页面

    返回一个静态html页面

    在工程目录下,创建一个templates目录,在templates目录创建a.html文件,代码如下:

    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <table id="g570b4" border="1">
            <tr id="g419fe">
                <th id="g16b02">th标头
                th>
                <th id="gaae0b">th标头
                th>
                <th id="gd78bc" class=" u5899e">地址
                th>
            tr>
            <tr id="g5af9b">
                <td id="g920bb">td表格单元
                td>
                <td id="g9de93" class=" uab6e6">td表格单元
                td>
                <td id="gea8dc">上海浦东虹桥某某小区某某地点
                td>
            tr>
            <tr id="cf47d6" class=" u0cbcd ">
                <td id="c913e3" class=" ud690a ">td表格单元
                td>
                <td id="c452e0" class=" uab6e6 ">td表格单元
                td>
                <td id="c917b3" class=" u7eb06 ">td表格单元
                td>
            tr>
            <tr id="cba81f" class=" u0cbcd ">
                <td id="c3dae7" class=" ud690a ">td表格单元
                td>
                <td id="c7d0f9" class=" uab6e6 ">td表格单元
                td>
                <td id="c9fe10" class=" u7eb06 ">td表格单元
                td>
            tr>
        table>
        <style>
            .u5899e {
                width: 162px;
            }
        style>
    body>
    
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    此时项目结构如下:
    在这里插入图片描述

    创建webapp_html.py文件,代码如下:

    from flask import Flask, render_template
     
    app = Flask(__name__)
     
     
    # “show”与函数index对应
    # 运行index函数返回templates目录下的index.html页面
    @app.route("/show")
    def index():
        return render_template("a.html")
     
     
    if __name__ == '__main__':
        app.run()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    运行代码

    python webapp_html.py
    
    • 1

    输出如下:

    (py10) PS D:\zjdemo> & D:/ProgramData/Anaconda3/envs/py10/python.exe d:/zjdemo/webapp_html.py
     * Serving Flask app 'webapp_html'
     * Debug mode: off
    WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
     * Running on http://127.0.0.1:5000
    Press CTRL+C to quit
    127.0.0.1 - - [20/Nov/2023 08:38:23] "GET / HTTP/1.1" 404 -
    127.0.0.1 - - [20/Nov/2023 08:38:28] "GET /show HTTP/1.1" 200 -
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    浏览器输入:

    http://127.0.0.1:5000/show
    
    • 1

    返回如下:
    在这里插入图片描述

    返回一个动态html页面

    在templates目录下创建一个jsdemo.html,代码如下:

    DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Documenttitle>
      <style>
        fieldset,#d1 {
          padding: 10px;
          width: 300px;
          margin: 0 auto;
        }
      style>
      
    head>
    <body>
      <form id="form1" name="form1" method="post" action="">
        <fieldset>
          <legend>按时legend>
          
          输入表格的行数:<input type="text" id="row" value="3" placeholder="请输入表格的行数" required autofocus><br>
          输入表格的列数:<input type="text" id="col" value="5" placeholder="请输入表格的列数" required autofocus><br>
          <input type="button" id="ok" value="产生表格" onclick="createTable()"/>
        fieldset>
      form>
      <div id="d1">div>
      <script type="text/javascript">
        function createTable(){
          n=1;
          var str="";var r1=document.getElementById("row").value;var c1=document.getElementById("col").value;for(i=0;i<r1;i++){
            str=str+"";for(j=0;j<c1;j++){
              str=str+"";}
            str=str+"";}var d1=document.getElementById("d1");
          d1.innerHTML=str+"
    "+(n++)+"
    "
    ; } createTable()
    script> body> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    在webapp_html.py中添加如下代码

    @app.route("/jsdemo")
    def jsdemo():
        return render_template("jsdemo.html")
    
    • 1
    • 2
    • 3
    重新启动web服务,运行代码
    
    ```python
    python webapp_html.py
    
    • 1
    • 2
    • 3
    • 4

    输出如下:

    (py10) PS D:\zjdemo> & D:/ProgramData/Anaconda3/envs/py10/python.exe d:/zjdemo/webapp_html.py
     * Serving Flask app 'webapp_html'
     * Debug mode: off
    WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
     * Running on http://127.0.0.1:5000
    Press CTRL+C to quit
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在浏览器中输入

    http://127.0.0.1:5000/jsdemo
    
    • 1

    返回为:
    在这里插入图片描述
    在浏览器中输入

    http://127.0.0.1:5000/show
    
    • 1

    返回为:
    在这里插入图片描述

    通过requests获取静态和动态html页面

    创建requestsdemo.py
    内容如下:

    import requests
    
    url_one = "http://127.0.0.1:5000/show"
    url_two = "http://127.0.0.1:5000/jsdemo"
    
    res_one = requests.get(url_one)
    print(res_one.content.decode('utf-8'))
    print("--------------------------")
    res_two = requests.get(url_two)
    print(res_two.content.decode('utf-8'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    运行代码,

    python .\requestsdemo.py
    
    • 1

    输出如下

    (py10) PS D:\zjdemo> python .\requestsdemo.py
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <table id="g570b4" border="1">
            <tr id="g419fe">
                <th id="g16b02">th标头
                </th>
                <th id="gaae0b">th标头
                </th>
                <th id="gd78bc" class=" u5899e">地址
                </th>
            </tr>
            <tr id="g5af9b">
                <td id="g920bb">td表格单元
                </td>
                <td id="g9de93" class=" uab6e6">td表格单元
                </td>
                <td id="gea8dc">上海浦东虹桥某某小区某某地点        
                </td>
            </tr>
            <tr id="cf47d6" class=" u0cbcd ">
                <td id="c913e3" class=" ud690a ">td表格单元
                </td>
                <td id="c452e0" class=" uab6e6 ">td表格单元
                </td>
                <td id="c917b3" class=" u7eb06 ">td表格单元
                </td>
            </tr>
            <tr id="cba81f" class=" u0cbcd ">
                <td id="c3dae7" class=" ud690a ">td表格单元
                </td>
                <td id="c7d0f9" class=" uab6e6 ">td表格单元
                </td>
                <td id="c9fe10" class=" u7eb06 ">td表格单元
                </td>
            </tr>
        </table>
        <style>
            .u5899e {
                width: 162px;
            }
        </style>
    </body>
    
    </html>
    --------------------------
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <style>
        fieldset,#d1 {
          padding: 10px;
          width: 300px;
          margin: 0 auto;
        }
      </style>
    
    </head>
    <body>
      <form id="form1" name="form1" method="post" action="">        
        <fieldset>
          <legend>按时</legend>
    
          输入表格的行数:<input type="text" id="row" value="3" placeholder="请输入表格的行数" required autofocus><br>
          输入表格的列数:<input type="text" id="col" value="5" placeholder="请输入表格的列数" required autofocus><br>
          <input type="button" id="ok" value="产生表格" onclick="createTable()"/>
        </fieldset>
      </form>
      <div id="d1"></div>
      <script type="text/javascript">
        function createTable(){
          n=1;
          var str="";
          var r1=document.getElementById("row").value;
          var c1=document.getElementById("col").value;for(i=0;i<r1;i++){str=str+"";for(j=0;j<c1;j++){str=str+"";}str=str+"";}
          var d1=document.getElementById("d1");
          d1.innerHTML=str+"
    "+(n++)+"
    "
    ; } createTable() </script> </body> </html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102

    可以看见,静态页面的源代码和浏览器渲染后的效果相匹配,但动态页面捕获到的源代码和浏览器渲染后的效果差别较大,无法通过xpath等方法获取数据。

    此时工程的完整目录如下:
    在这里插入图片描述

    备注:html渲染的过程
    说说页面渲染的过程
    浏览器渲染流程(精讲)

    总结

    本文主要描述了flask安装与返回静态页面和动态页面的过程,并通过requests库分布爬取静态/动态页面,通过比较可以更清晰的了解页面动态渲染的意义,以及引出selenium库的作用。

  • 相关阅读:
    【11.12】Codeforces Round #833 (Div. 2)
    基于RabbitMQ的模拟消息队列之六——网络通信设计
    java将文件夹压缩成压缩包
    【实践篇】Redis最强Java客户端Redisson
    【无标题】
    【学习笔记之菜Dog学C】动态内存管理
    Vue2.0开发之——webpack基础-resolve指定默认路径(12)
    PCL入门(一):ubuntu20使用apt安装pcl
    OpenCV中LineTypes各枚举值(LINE_4 、LINE_8 、LINE_AA )的含义
    「建模学习」听说3D建模很难,原来不是学不会,而是缺少这个
  • 原文地址:https://blog.csdn.net/m0_38139250/article/details/134499193