什么是Web服务器
可以为发出请求的浏览器提供静态文档的程序。
平时我们浏览百度新闻数据的时候,每天的新闻数据都会发生变化,那访问的这个页面就是动态的,而我们开发的是静态的,每天访问我们自己的静态web服务器,页面的数据不会发生变化。
Web服务器的工作原理
- 用户在终端发出访问请求
- 通过tcp协议建立链接
- 生成http报文发送到静态Web服务器中
- 服务器解析报文, 并把用户申请的资源打包成http报文发送给用户
- 应答体中携带的数据发送到浏览器,浏览器经过渲染产生具体页面
Python搭建简易的Web服务器
1. 搭建服务器端的基本步骤: 导入socket包, 创建套接字对象, 设置端口复用, 绑定IP和端口号, 设置监听, 接受客户端的数据
import socket # 创建套接字对象 web_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设置端口复用 web_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) # 绑定IP和端口 web_server.bind(('',8001)) # 设置监听 web_server.listen(128) # 接受客户端HTTP报文 while True: new_socket, ip_post = web_server.accept() recv_data = new_socket.recv(1024)
打印出用户端请求的HTTP报文, 我们可以看到下面的几个部分:
- 请求行: 请求方法GET, 请求的界面, 使用的协议
- 请求头: 客户端的具体信息
- 空行: 空行
为了获取用户具体的请求界面, 对HTTP请求报文做出处理, 通过切割切片可以获得用户具体的资源
if recv_data: recv_data = recv_data.decode('utf-8') request_list = recv_data.split(' ',maxsplit=2) url = request_list[1][1:]
然后就根据用户请求的资源打包成HTTP响应报文发送给用户即可
注意: 发送的数据要组成HTTP报文的形式, 响应行, 响应头, 空行, 响应体都却以不可
如果服务器没有用户请求的资源, 返回找不到资源给用户, 这里需要注意响应行的状态不同
try: with open(url, 'rb') as f: data = f.read() except: # 报错没有找到 # 响应行 http_line = 'Http/1.1 404 Not Found\r\n' # 响应头 http_header = 'Server:PythonWeb\r\nContent_type = text/html;charset=utf-8 \r\n' # 空行 http_body = "sorry, can't find the resource..." response = (http_line+http_header+'\r\n'+http_body).encode('utf-8') new_socket.send(response) else: # 没报错, 找到文件 http_line = 'Http/1.1 200 OK\r\n' http_header = 'Server:PythonWeb\r\n' response = (http_line + http_header + '\r\n').encode('utf-8') + data new_socket.send(response) finally: new_socket.close()
最终的代码如下:
import socket # 创建套接字对象 web_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设置端口复用 web_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) # 绑定IP和端口 web_server.bind(('',8001)) # 设置监听 web_server.listen(128) while True: new_socket, ip_post = web_server.accept() recv_data = new_socket.recv(1024) if recv_data: recv_data = recv_data.decode('utf-8') request_list = recv_data.split(' ',maxsplit=2) url = request_list[1][1:] print(url) # 返回http报文 try: with open(url, 'rb') as f: data = f.read() except: # 报错没有找到 # 响应行 http_line = 'Http/1.0 404 NotFound\r\n' # 响应头 http_header = 'Server:PythonWeb\r\nContent_type = text/html;charset=utf-8 \r\n' # 空行 http_body = "sorry, can't find the resource..." response = (http_line+http_header+'\r\n'+http_body).encode('utf-8') new_socket.send(response) else: # 没报错, 找到文件 http_line = 'Http/1.0 200 OK\r\n' http_header = 'Server:PythonWeb\r\n' response = (http_line + http_header + '\r\n').encode('utf-8') + data new_socket.send(response) finally: new_socket.close()
尝试访问服务器的内容, 发现可以正常访问
FastAPI
FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框架,使用 Python 并基于标准的 Python 类型提示。
关键特性:
快速:可与 NodeJS 和 Go 并肩的极高性能(归功于 Starlette 和 Pydantic)最快的 Python web 框架之一。
高效编码:提高功能开发速度约 200% 至 300%。*
- 更少 bug:减少约 40% 的人为(开发者)导致错误。
- 智能:极佳的编辑器支持。处处皆可自动补全,减少调试时间。
- 简单:设计的易于使用和学习,阅读文档的时间更短。
- 简短:使代码重复最小化。通过不同的参数声明实现丰富功能。bug 更少。
- 健壮:生产可用级别的代码。还有自动生成的交互式文档。
- 标准化:基于(并完全兼容)API 的相关开放标准:openapi (以前被称为 Swagger) 和 JSON Schema .
使用FastAPI, 可以快速构建Web服务器
1. 配置FastAPI环境
在终端中输入以下命令下载相关资源包
pip install fastapi
pip install uvicorn
2.导入如下资源包后, 使用FastAPI实例化对象app, 然后定义函数,
在函数中读取相关的资源文件, 然后返回Response对象, content参数是读取的文件数据, media_type是文件类型, html类型数据
最后使用app.get()方法装饰函数, 参数为url, 用户请求的资源的地址
from fastapi import FastAPI from fastapi import Response import uvicorn app = FastAPI() @app.get('/China_Daily_Website.html') def China_Daily_Website(): with open('China_Daily_Website.html','rb') as f: data = f.read() return Response(content=data, media_type='text/html') @app.get('/TED.html') def TED(): with open('TED.html','rb') as f: data = f.read() return Response(content=data, media_type='text/html')
3.在uvicorn中运行, 第一个参数是FastAPI框架, 第二个参数的绑定的IP地址, 第三个是绑定的端口号
uvicorn.run(app, host='192.168.68.112',port=8000)
运行代码, 正常访问界面
因为我没有下载网页的图片, 所以没有显示出来, 如果你有网页的全部资源, 是可以正常显示的
完整代码
from fastapi import FastAPI from fastapi import Response import uvicorn app = FastAPI() @app.get('/China_Daily_Website.html') def China_Daily_Website(): with open('China_Daily_Website.html','rb') as f: data = f.read() return Response(content=data, media_type='text/html') @app.get('/TED.html') def TED(): with open('TED.html','rb') as f: data = f.read() return Response(content=data, media_type='text/html') uvicorn.run(app, host='192.168.68.112',port=8000)