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

python构建web服务

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

flask安装与运行测试

安装flask

pip install flask

创建一个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()


运行代码

 python webapp.py

终端输出如下:

& 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 -

在浏览器输入

http://127.0.0.1:5000

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

flask返回复杂的html字符串

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

from flask import Flask

# 用当前脚本名称实例化Flask对象,方便flask从该脚本文件中获取需要的内容
app = Flask(__name__)


html_str="""
<!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>

"""

#程序实例需要知道每个url请求所对应的运行代码是谁。
#所以程序中必须要创建一个url请求地址到python运行函数的一个映射。
#处理url和视图函数之间的关系的程序就是"路由",在Flask中,路由是通过@app.route装饰器(以@开头)来表示的
@app.route("/")
#url映射的函数,要传参则在上述route(路由)中添加参数申明
def index():
    return html_str

# 直属的第一个作为视图函数被绑定,第二个就是普通函数
# 路由与视图函数需要一一对应
# def not():
#     return "Not Hello World!"

# 启动一个本地开发服务器,激活该网页
app.run()


运行
运行代码

 python webapp.py

在浏览器输入

http://127.0.0.1:5000

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

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>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>

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

创建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()

运行代码

python webapp_html.py

输出如下:

(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 -

浏览器输入:

http://127.0.0.1:5000/show

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

返回一个动态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>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="<table width='100%' border='1' cellspacing='0' cellpadding='0'><tbody>";
      var r1=document.getElementById("row").value;
      var c1=document.getElementById("col").value;
      for(i=0;i<r1;i++)
      {
        str=str+"<tr align='center'>";
        for(j=0;j<c1;j++)
        {
          str=str+"<td>"+(n++)+"</td>";
        }
        str=str+"</tr>";
      }
      var d1=document.getElementById("d1");
      d1.innerHTML=str+"</tbody></table>";
    }
    createTable()
  </script>
</body>
</html>

在webapp_html.py中添加如下代码

@app.route("/jsdemo")
def jsdemo():
    return render_template("jsdemo.html")
重新启动web服务,运行代码

```python
python webapp_html.py

输出如下:

(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

在浏览器中输入

http://127.0.0.1:5000/jsdemo

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

http://127.0.0.1:5000/show

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

通过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'))

运行代码,

python .\requestsdemo.py

输出如下

(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="<table width='100%' border='1' cellspacing='0' cellpadding='0'><tbody>";
      var r1=document.getElementById("row").value;
      var c1=document.getElementById("col").value;
      for(i=0;i<r1;i++)
      {
        str=str+"<tr align='center'>";
        for(j=0;j<c1;j++)
        {
          str=str+"<td>"+(n++)+"</td>";
        }
        str=str+"</tr>";
      }
      var d1=document.getElementById("d1");
      d1.innerHTML=str+"</tbody></table>";
    }
    createTable()
  </script>
</body>
</html>

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

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

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

总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/166767.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux常用命令——bunzip2命令

在线Linux命令查询工具 bunzip2 创一个bz2文件压缩包 补充说明 bunzip2命令解压缩由bzip2指令创建的”.bz2"压缩包。对文件进行压缩与解压缩。此命令类似于“gzip/gunzip”命令&#xff0c;只能对文件进行压缩。对于目录只能压缩目录下的所有文件&#xff0c;压缩完成…

信息安全和网络空间安全选哪个?

网络空间安全和信息安全这2个专业都是计算机专业&#xff0c;而且是最适合走网络安全方向的2个热门专业&#xff0c;那么它们有什么不一样&#xff1f;又该如何选择&#xff1f;过来人告诉你答案。 一、相同之处 1. 目标相同 网络空间安全专业和信息安全专业都致力于保护计算…

SpringBoot3.x最简集成SpringDoc-OpenApi

为什么使用SpringDoc 在SpringBoot低版本时一般使用Swagger扫描接口生成Json格式的在线文档&#xff0c;然后通过swagger-ui将Json格式的文档以页面形式展示文档。可惜遗憾的是swagger更新到3.0.0版本(springfox)后不更新了。 SpringBoot3.x以后需要的JDK版本最低为Java17&…

Go并发编程学习-class1

class1. Mutex 解决资源并发访问 基础概念 临界区概念&#xff1a;一个被共享的资源&#xff0c;可以被并发访问。通过Mutex互斥锁&#xff0c;可以限定临界区只能由一个线程获取。 根据不同情况&#xff0c;不同适用场景 ●共享资源。并发地读写共享资源&#xff0c;会出现…

X12学习手册

EDI术语中的X12是指ANSI X12 报文标准&#xff08;EDI Document Standard&#xff09;&#xff0c;于 1979 年发布&#xff0c;由认证标准委员会维护&#xff0c;在过去的几十年中得到扩展&#xff0c;以满足全球业务流程的要求&#xff0c;包括汽车、物流、零售、医药、金融、…

多域名SSL证书的优势

当今数字化时代&#xff0c;网站拥有一个或多个域名是非常常见的。多域名SSL证书在这样的情境下变得至关重要。它为拥有多个域名的网站提供了全面的安全性和灵活性&#xff0c;为其提供了诸多优势。 多域名SSL证书是一种单个证书&#xff0c;可以为一个域名、多个域名&#xff…

SVG图片在HTML页面中的四种加载方法

HTML专栏是汇集了一些HTML常常被遗忘的知识&#xff0c;这里算是温故而知新&#xff0c;往往这些零碎的知识点&#xff0c;在你开发中能起到炸惊效果。我们每个人都没有过目不忘&#xff0c;过久不忘的本事&#xff0c;就让这一点点知识慢慢渗透你的脑海。 本专栏的风格是力求简…

如何做到低风险的部署与发布?(下)丨IDCF

灰度发布 灰度发布是在金丝雀发布基础上进行延伸&#xff0c;不是将发布分成两批&#xff0c;而是将发布分成不同的阶段/批次发布&#xff0c;每个阶段/批次的用户数量逐级增加。如果新版本在当前阶段没有发现问题&#xff0c;就再扩展用户数量进入下一个阶段&#xff0c;直至扩…

everything的高效使用方法

目录 前言1 everything的简单介绍2 常用搜索3 语法搜索4 正则表达式搜索5 服务器功能 前言 本文介绍everything软件的高效使用方法&#xff0c;everything是一款在系统中快速搜索文件的软件&#xff0c;能够帮助人们快速定位需要查找的文件。首先介绍everything软件的作用和使…

自学人工智能该从哪里开始准备?

随着人工智能技术的飞速发展&#xff0c;越来越多的人对学习人工智能产生了浓厚的兴趣。然而&#xff0c;对于许多初学者来说&#xff0c;不知道如何开始自学人工智能。今天&#xff0c;我将向大家介绍一些自学人工智能的步骤&#xff0c;帮助大家更好地入门这个领域。 第一步&…

基于SSM的奖助学金管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

【MATLAB】史上最全的9种频谱分析算法全家桶

有意向获取代码&#xff0c;请转文末观看代码获取方式~ 大家吃一顿火锅的价格便可以拥有9种频谱分析算法&#xff0c;绝对不亏&#xff0c;知识付费是现今时代的趋势&#xff0c;而且都是我精心制作的教程&#xff0c;有问题可随时反馈~也可单独获取某一算法的代码&#xff08…

基于SSM的焦作旅游协会管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

应用程序生成器:App Builder 2023

DecSoft应用程序生成器 专为小屏幕设备设计&#xff0c;但也可以&#xff08;无需更改&#xff09;部署在平板电脑等较大设备中。 如果您想创建现代桌面和移动应用程序&#xff0c;那么您来对地方了&#xff01;DecSoft App Builder 是一个专业的可视化开发环境&#xff0c;用于…

【LeetCode刷题笔记】链表

141. 环形链表 解题思路: 1. 哈希表 , 最容易想到的方法是遍历所有节点,每次遍历到一个节点时,判断该节点此前是否被访问过。 2. 快慢指针 「Floyd 判圈算法」(又称龟兔赛跑算法)快慢指针从 head 开始走, 慢指针每次只移动1步 ,而 快指针每次移动2步 。 如果在移动的过程…

常用的OLED透明显示屏款式,有几种?

作为OLED透明屏的制造工程师&#xff0c;尼伽小编对这一领域的发展和技术进步有着丰富的经验和深入的理解。在本文中&#xff0c;我将为大家介绍一些关于OLED透明显示屏款式的知识&#xff0c;并探讨其在未来的应用前景。 OLED透明显示屏作为新一代的显示技术&#xff0c;其独特…

实人认证API的出现,让电子化身份验证更加可靠

前言 随着信息技术的快速发展和数字化转型的加速&#xff0c;各种电子化应用正在走进人们的生活中&#xff0c;电子化身份验证也成为了日益普遍的需求。从现在生活中各种App、网站、电商平台等需要身份认证的场景来看&#xff0c;身份验证的确是十分重要的一环。但是&#xff…

监控电脑的软件叫什么丨科普小知识

监控电脑的软件叫电脑监控软件。 电脑监控软件是一种可以监控电脑使用情况的软件&#xff0c;通常具有记录屏幕活动、网站访问、聊天记录等功能。 应用场景 1、企业内部管理&#xff1a;企业管理者可以通过监控电脑软件来监视员工的工作活动&#xff0c;以确保员工遵守公司政…

基于Pyflwdir实现流域的提取(参照官网例子)

本文参照官网例子实现流域的提取,官方GitHub地址如下pyflwdir&#xff1a; 该工具包目前仅支持D8和LDD两种算法&#xff0c;在效率上具有较好的应用性&#xff0c;我用省级的DEM&#xff08;30米&#xff09;数据作为测试&#xff0c;输出效率可以满足一般作业需要。 环境env…

微信怎么发状态?简单教程,一学就会!

微信是一个非常实用的社交应用&#xff0c;不仅提供了基础的聊天功能&#xff0c;还推出了很多其他有趣的功能。比如微信个人状态&#xff0c;这个功能可以让用户随时随地分享自己的心情和动态。那么&#xff0c;微信怎么发状态呢&#xff1f;本文将为大家介绍有关微信发状态的…