2022-回放-06:Web 开发导论(HTTP 与 Web 技术演变)· Flask 实战 · FastAPI 初识¶
内容梗概¶
本次直播回放是课程三大实战模块(Web 开发 → Web 爬虫 → 数据可视化)的开端。老师先阐述了三次实战课层层递进的设计逻辑(Web 开发是互联网基石;爬虫方案恰好对应 Web 技术架构的演变;爬取的数据再拿去做可视化),随后用画图的方式从零推演 Web 的基本概念:HTTP 协议、web 服务器、静态网页、后端动态生成、AJAX、前后端分离四个发展阶段,并用 HFS 软件、百度首页、B 站弹幕做了现场演示。后半场进入 Flask 实战:用 pipenv 建虚拟环境、写第一个 Flask 应用、路由与装饰器、templates 模板与 Jinja 语法、static 静态文件、debug 模式。最后对照演示了 FastAPI 的最小示例(uvicorn 运行、自动返回 JSON、路径参数、typing 类型标注),并布置了"用 Flask 做一个博客性质网站"的作业。
知识点详解¶
一、课程结构说明(约 00:00 - 07:20)¶
- 后三次实战是阶梯关系:Web 开发 → Web 爬虫 → 数据可视化。
- Web 开发是互联网的基石:绝大多数 App 本质是"混合应用"(Web 技术套壳),小程序的 WXML 是 HTML 的变种。
- 爬虫方案与 Web 技术架构演变一一对应:静态站直接爬、动态站要处理 JS 渲染甚至用无头浏览器;从开发者视角思考目标站的数据组织与前后端对接方式,是爬虫的关键思路,也体现安全专业"对抗"的内核。
- 数据可视化:爬来的几千几万条数据靠工具处理,如统计词频(TF-IDF)、画词云。
- 授课思路说明:以 Python 为线索串起计算机领域的知识体系;实战部分每个单点不求讲透,而是提供"索引",供学生按脉络自行展开。
二、Web 基本概念与技术演变(约 07:20 - 01:08:30)¶
- 最原始形态(约 07:50):Web 本质 = 通过 HTTP 协议(超文本传输协议)传输一串文本并在浏览器显示。对面电脑有个文件夹 A,浏览器想看里面的 1.txt——需要双方先约定"暗号",这就是协议。
- HTTP 方法(约 10:55):约定若干动作——GET(从对方获取)、POST(往对方发送)、PUT/UPDATE(更新已传内容)、DELETE(删除)。请求行如
GET /1.txt,路径本质是相对 web 目录的相对路径。 - web 服务器(约 13:50):右边电脑也需要软件解析 HTTP 请求并操作文件夹,即 web server(WS):收到
GET /就列出目录内容,收到GET /1.txt就返回文件内容。常见 web 服务器:Apache、Nginx、Tomcat(Java 系)。 - 端口与多站点(约 15:50 - 17:30):web server 通过配置文件把端口映射到目录(80 端口 ↔ A 文件夹);http 默认 80 端口、https 默认 443,访问
:8080说明开了第二个站点对应 B 文件夹——一台机器可同时跑 N 个网站。 - HFS 演示(约 17:50 - 21:50):用 Http File Server(约 2.5MB 小软件)现场演示:
add folder from disk把桌面 demo 文件夹映射为/demo,浏览器访问即可看到 1.txt、2.txt 的内容——浏览器与 web server 甚至可以在同一台机器上。 - 阶段一:静态网页(约 22:00 - 26:50):需求升级(富文本:加粗、标题、图片)催生了 HTML。所有 web server 默认会在路径下寻找
index.html并自动打开(约定俗成,index = 索引),这就是为什么网页课第一个文件总叫 index.html。静态网页一保存内容就固定,连"您是第 N 位访客"都做不到。 - 阶段二:后端动态生成(约 26:50 - 33:00):web server 后面不再直接对文件夹,而是转发给一个**程序**(Python / PHP / Java / C 都行):根据 URL 路径找到对应脚本和函数,把 GET 参数(
?id=256问号后面是参数、前面是路径)传进去,函数生成一个符合 HTML 格式的字符串返回——页面"动"起来了。PHP 在安全领域常见(老站多、题多)。局限:拿到 HTML 后不再发请求,不按 F5 页面不会变——做不了弹幕。 - 阶段三:AJAX(约 33:00 - 41:20):返回的不只 HTML,还有 CSS(管样式)和 JavaScript(管交互、在浏览器里运行)。JS 可以不刷新页面偷偷再发 GET 请求(如每秒取一次弹幕),拿到数据后修改页面局部元素。AJAX = Asynchronous JavaScript And XML:异步(不等上一个请求返回就能发下一个)、早期数据格式是 XML。
- 阶段四:前后端分离(约 41:20 - 57:45):阶段三下后端生成 HTML、前端 JS 也改 HTML,两者"抢活"产生分歧;于是分家——前端(Node.js 生态的 Vue / React / Angular 框架)全权负责 HTML 呈现,后端(Python/PHP 等)只提供 URL 接口、返回数据。数据格式从 XML 演变为 JSON(JavaScript Object Notation):XML 复杂且像 HTML,JSON 长得像 Python 字典、能被 JS 原生解析,现在互联网上 99% 用 JSON(机制仍叫 AJAX)。前后端可跑在不同服务器上,后端可做负载均衡;多终端共用同一后台(浏览器/App/小程序/平板访问 B 站,数据一样只是呈现不同)——这是前后端分离成为大趋势的根本原因。
- 实例观察(约 57:50 - 01:08:30):
- 百度首页:直接爬到的 HTML 是空架子(logo、搜索框、热搜都不在里面),里面一堆
<script>;浏览器运行 JS 后用 AJAX 取数据再修改 HTML 渲染出页面。爬虫不是浏览器、没有 JS 运行环境,所以爬到的页面和看到的不一致——这是爬虫失败的常见原因。 - B 站直播弹幕:F12 开发者工具 → 网络 → 过滤 Fetch/XHR,双手离开键盘也能看到请求数不断增长——JS 在后台持续取弹幕。百度首页则加载后不再发新请求,只用 JS 修改自身元素。
三、Flask 实战(约 01:08:30 - 01:58:50)¶
- 框架对比:Python 常见 web 框架三个——Flask(轻量级、小而精、功能靠插件,适合教学)、Django(大而全、开箱即用,讲起来太庞大)、FastAPI(新生框架,天生为前后端分离的纯后端 API 设计)。Flask 设计之初是阶段三方案(含前端模板),装插件后也能做阶段四。
- 作业要求(约 01:11:40 与结尾 02:25:30):用 Flask 做一个网站(博客、新闻站、班级网站均可);老师会建空仓库,不提供任何结构化文件;录播的 Flask 实例视频有 40 多分钟从零做博客的全流程,跟着做一定能做出来。
- 项目初始化(约 01:14:25):新建文件夹 → VS Code 打开 → 终端
pipenv install建虚拟环境 → 改Pipfile里的源为国内镜像 →pipenv shell进入环境 →pipenv install flask。VS Code 右下角要选择刚创建的虚拟环境,否则 import 处有波浪线。 - 最小应用(约 01:16:35):新建
app.py(web 应用也叫 app):from flask import Flask # 导入 Flask 类 app = Flask(__name__) # 实例化应用 @app.route('/') # 装饰器:定义路由,把路径绑定到函数 def index(): return 'hello world'@app.route('/')写在函数前是**装饰器**(原理见"函数与类"章节视频),含义:用户访问该路径时自动运行对应函数——一种路径与函数的绑定关系。 - web server 在哪里(约 1:22:50 - 1:28:00):Flask 内置了开发用 web 服务器(Werkzeug,德语"工具"),它承担两个角色:① 接收浏览器的 HTTP 请求;② 自动找到并执行
app.py。开发学习阶段不需要单独装 Apache/Nginx。文件名默认必须是app.py;若叫别的名字(如hello.py),需设置环境变量FLASK_APP=hello再运行。 - 两种运行方式(约 01:29:00):
- 代码末尾加
app.run(),直接python app.py(符合直觉); - 命令行
flask run(官方方式)。注意:flask run本质上也是导入执行 app.py,若文件里裸写app.run()会重复运行,所以要用if __name__ == '__main__':包起来——正好用上模块与包章节的知识。 - templates 模板(约 01:33:00 - 01:44:00):动态页面的 HTML 大部分内容人人相同,只有局部要改——把整体 HTML 叫**模板**(类比群发邀请函只改姓名/称谓)。Flask 内置规则:默认去
app.py同级目录下找templates文件夹;视图函数改为return render_template('index.html')(需from flask import render_template)。路径是相对 templates 的相对路径(如子目录就写'pub/index.html');强迫症想改文件夹名,可在Flask(__name__, template_folder='abc')里指定。 - Jinja 模板语言(约 01:45:00 - 01:53:30):所有现代 web 框架都有自己的模板语言(Java 的 JSP 同理);Flask 用 Jinja。HTML 里写
{{ name }}(双大括号)表示此处显示 Python 传来的变量;后端render_template('index.html', name=username)传参(前一个 name 是模板里的变量名,后一个是函数内变量)。还可用{% %}做分支/循环(语法见录播视频,含模板继承)。演示:首页显示"欢迎{username}来到我的首页"+ 用datetime.now().strftime('%Y-%m-%d %H:%M:%S')显示当前时间(%Y 四位年份、%m 月、%d 日、%H 时、%M 分、%S 秒,老师也是现场查的)。 - static 静态文件(约 01:54:00 - 01:58:00):CSS、JS、图片等不需要后端计算的文件叫静态文件,默认放
static文件夹(可再分 css/js/image 子目录),HTML 里用 link 等标签引用。可用Flask(__name__, static_folder='...')改名;甚至static_host参数可把静态文件放到另一台服务器——浏览器拿到 HTML 后自己去那台服务器下载静态资源,实现**数据/计算与静态资源分离**,减轻 app 服务器压力(进阶内容,不懂不影响)。 - debug 模式(约 01:39:50、01:41:30):
app.run(debug=True)开启后,改代码 Ctrl+S 保存即自动 reload(终端显示 detected change... reloading),不用反复 Ctrl+C 重启。上线必须关掉:否则报错会把路径、代码细节直接打在网页上造成信息泄露(网安人的职业素养)。
四、FastAPI 初识(约 01:59:40 - 02:25:30)¶
- 目的:通过对比理解阶段四(前后端分离)的框架长什么样。
- 安装与示例(约 02:00:40):新建目录 → pipenv 老套路(改源)→
pipenv install fastapi;uvicorn 需单独装:pipenv install "uvicorn[standard]"(方括号语法表示安装其基于 C 扩展的一系列额外依赖)。官方示例文件名是main.py。 - 最小示例:
运行用
from fastapi import FastAPI app = FastAPI() @app.get('/') # 直接把 HTTP 方法写进装饰器 def read_root(): return {'Hello': 'World'}uvicorn main:app(main:app= 文件名:应用对象名,uvicorn 相当于 Flask 的内置服务器 + 调度器双重角色,默认端口 8000)。 - 自动返回 JSON(约 02:09:50):FastAPI 的示例根本不出现 HTML——视图函数返回 Python 字典,框架自动转成符合 JSON 格式的字符串发给前端。Flask 也能返回 JSON 但要手工转换,FastAPI 是全自动——它天生只为"返回数据"设计。
- 路径参数(约 02:18:00):
/items/{item_id}把参数写进路径(区别于?id=233的 GET 参数),如/users/233访问 ID 为 233 的用户;函数def read_item(item_id: int, q: str = None)自动从路径取参。Flask 也支持这种写法。 - typing 类型标注(约 2:06:00):示例里
q: Union[str, None] = None、def f(name: str) -> str是 Python 3.5+ 的类型提示语法——弥补 Python 变量无类型导致的"调用者乱传参"问题;->标注返回值类型。 - flask.py / abc.py 翻车(约 02:00:00、02:14:00):项目文件夹不能叫
flask(import flask 会找到自己、循环依赖);把main.py改名abc.py后 uvicorn 报错——因为 Python 标准库真有一个叫abc的模块(abstract base classes),被优先搜到;改成"anjing.py"立刻成功。生动复习了模块搜索路径知识。 - 框架选择建议:做大创等项目时,前后端分离模式下后端用 FastAPI 只管数据,前端交给会 Vue/React 的同学;Flask 也在向这个方向发展。
示例与演示¶
- HFS 静态文件服务器:把桌面 demo 文件夹映射为
/demo,浏览器访问列出并打开 1.txt/2.txt,演示"HTTP 取文件"的最原始形态。 - 百度首页源代码:右键查看源代码几乎找不到实质内容(空 HTML + 一堆 script),说明页面靠 JS 渲染;对比 B 站直播页 F12 的 Fetch/XHR 请求持续增长(弹幕 AJAX 轮询)。
- Flask 从零建站:pipenv 初始化 → 写
app.py(路由/返回 hello world、/about返回"我")→ 两种运行方式 → 加templates/index.html用render_template渲染 → Jinja{{ name }}传用户名和当前时间 → 建static文件夹 → 开 debug 热重载。 - FastAPI 最小示例:官方 example 复制为
main.py→uvicorn main:app→ 浏览器访问/得到{"Hello":"World"},访问/items/1?q=xxx演示路径参数与查询参数。 - 作业:用 Flask 做一个博客性质的网站(想挑战可用 Vue + FastAPI,但基准要求是 Flask);老师建空仓库,跟着 40 分钟的 Flask 实例录播视频可完成。
重点与难点¶
- Web 四阶段演变(静态 → 后端动态生成 → AJAX 局部刷新 → 前后端分离)是整节课的主线,也是理解爬虫策略的钥匙:爬动态渲染页面时,直接拿到的 HTML 是空壳。
- AJAX 的名字来源(异步 JavaScript and XML)与"JSON 取代 XML 但名字没改"的历史;JSON 与 Python 字典形态一致。
- HTTP 请求结构:路径 vs
?后的 GET 参数 vs 路径内嵌参数(/items/{id})三种传参位置。 - Flask 的"内置规则":
app.py文件名、templates文件夹、static文件夹都是默认约定,可通过Flask()参数(template_folder、static_folder、static_host)覆盖。 @app.route装饰器 = 路径与函数的绑定;flask run时务必用if __name__ == '__main__':包住app.run(),否则重复运行。- debug 模式仅用于开发,上线必须关闭(信息泄露风险)。
- 文件/目录命名不要与标准库、第三方库重名(flask 目录、abc.py 两次现场翻车);标准库里有
abc(abstract base classes)模块。 - uvicorn 的启动参数
main:app是"模块:应用对象",改名要两处一起改。
关联内容¶
- 直接承接上一讲(回放-05)的"模块与包、第三方库与虚拟环境":pipenv/Pipfile 工作流、
if __name__ == '__main__'、模块搜索路径在本课全部复用并翻车验证。 - 装饰器原理见录播章节"函数进阶与类";Flask 完整实例(模板继承、Jinja 语法、40 分钟博客实战)在对应录播视频中。
- 本课是后续"Web 爬虫"的直接前置:爬虫各方案对应本课的 Web 架构演变(静态页直接爬 → AJAX 站需分析接口或用无头浏览器);再往后接"数据可视化"(词频统计、词云)。
- 前后端分离部分提及的 Vue/React/Angular、Node.js 不属于本课程内容,仅作方向指引;相对路径/绝对路径、环境变量等前置知识来自早期章节与《计算机安全与维护》。