Python Day26 HTTP 协议相关笔记
1. HTTP 协议基础
- 协议层级:HTTP 是应用层协议,其下层(数据传输层)基于 TCP 协议实现可靠的数据传输。
- 核心作用:定义客户端(如浏览器)与服务器之间的请求和响应格式,实现超文本(如 HTML、图片等)的传输。
2. HTTP 响应数据格式(严格要求)
HTTP 响应由三部分组成,格式如下:
状态行\r\n
响应头1: 值1\r\n
响应头2: 值2\r\n
...\r\n (空白行,用于分隔响应头和正文)
响应正文
状态行(第一行)
格式:协议版本 状态码 状态文本描述
示例:HTTP/1.1 200 OK
常见状态码及含义:- 200 OK:请求成功
- 404 Not Found:请求的资源不存在
- 500 Internal Server Error:服务器内部错误
- 302 Found:资源临时重定向
- 403 Forbidden:服务器拒绝请求
响应头(第二行及后续,每行一个)
用于描述响应的元信息,常见头信息:Connection: keep-alive
:设置连接状态(保持连接,避免频繁建立 TCP 连接)Content-Encoding: gzip
:指定响应内容的压缩方式(如 gzip 压缩可减少传输数据量)Content-Type: text/html;charset=utf-8
:核心头信息,指定响应正文的数据格式和编码(如text/plain
纯文本、application/json
JSON 数据、image/jpeg
图片等)Content-Length: 1024
:指定响应正文的字节长度(帮助客户端确认数据是否完整接收)
响应正文
服务器返回的实际数据(如 HTML 内容、JSON 数据、图片二进制等),必须与响应头中的Content-Type
匹配。
注意:正文与响应头之间必须有一个空白行(\r\n
)分隔。
3. 简易 HTTP 服务器实现(Python 示例)
以下代码通过socket
和threading
实现一个简易 HTTP 服务器,可处理客户端请求并返回对应 HTML 文件:
import socket
import threading
import osdef handler_task(client: socket.socket):# 接收客户端请求(最多8KB数据)并解码message = client.recv(8 << 10).decode()# 解析请求(第一行为请求行:方法 路径 协议)lines = message.split("\r\n")method, path, protocol = lines.pop(0).split(' ') # 如:GET /index HTTP/1.1# 解析请求头(键值对形式)headers = dict([line.split(": ", maxsplit=1) for line in lines[:-2]])# 构造响应模板template = "HTTP/1.1 {status} {status_text}\r\n" \"Connection: keep-alive\r\n" \"Content-Type: text/html;charset=utf-8\r\n" \"\r\n" \"{body}"# 根据请求路径查找对应HTML文件filename = f"{path[1:]}.html" # 如路径为/index,则查找index.htmlif os.path.exists(filename):# 资源存在:返回200 OK和文件内容status = 200status_text = "OK"with open(filename, "r", encoding="utf-8") as f:body = f.read()else:# 资源不存在:返回404 Not Foundstatus = 404status_text = "Not Found"body = "<h1>Not Found</h1>"# 填充模板并发送响应response = template.format(status=status, status_text=status_text, body=body)client.send(response.encode())# 关闭客户端连接client.close()if __name__ == '__main__':# 创建TCP socketserver_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 绑定地址(0.0.0.0表示监听所有网卡,端口8080)server_socket.bind(('0.0.0.0', 8080))# 开始监听(最大等待连接数5)server_socket.listen(5)print("Server started on port 8080...")while True:# 接受客户端连接(阻塞操作)client_socket, client_addr = server_socket.accept()# 启动线程处理该客户端请求(支持并发)threading.Thread(target=handler_task, args=(client_socket,)).start()
代码说明:
- 服务器通过
socket
监听端口,使用多线程处理多个客户端并发请求。 - 解析客户端请求的路径,若对应 HTML 文件存在则返回文件内容,否则返回 404 页面。
- 响应格式严格遵循 HTTP 协议规范(状态行、响应头、空白行、正文)。
二、正则表达式修饰符(匹配模式)
正则表达式的修饰符用于改变匹配规则,常见修饰符及作用如下:
1. re.I
(忽略大小写匹配)
- 作用:匹配时忽略字母的大小写(仅对英文字母有效)。
- 示例:
import re string = 'aBc' regex = r"^[a-z]+$" ret = re.match(regex, string, re.I) # 匹配成功,忽略大小写 print(ret) # <re.Match object; span=(0, 3), match='aBc'>
2. re.S
(dotAll 模式)
- 作用:使
.
可以匹配任何字符(包括换行符\n
,默认情况下.
不匹配\n
)。 - 示例:
import re string = 'a\nb' # 默认模式:.不匹配\n,匹配失败 ret1 = re.match(r"a.b", string) # re.S模式:.匹配\n,匹配成功 ret2 = re.match(r"a.b", string, re.S) print(ret1) # None print(ret2) # <re.Match object; span=(0, 3), match='a\nb'>
3. re.M
(多行匹配模式)
- 作用:配合
^
和$
使用时,^
匹配每行的开头(而非整个字符串的开头),$
匹配每行的结尾(而非整个字符串的结尾)。 - 示例:
import re string2 = """ aBc 123 txy t15 """ # 匹配每行纯字母(忽略大小写+多行模式) regex = r"^[a-z]+$" ret = re.findall(regex, string2, re.M | re.I) # 同时使用两个修饰符(用|连接) print(ret) # ['aBc', 'txy'](匹配到两行纯字母)
4. 其他常用修饰符
re.X
(VERBOSE 模式):忽略正则表达式中的空格和注释(便于编写复杂正则)。
示例:regex = r""" ^[a-z]+ # 匹配小写字母开头 \d*$ # 可选数字结尾 """ ret = re.match(regex, "abc123", re.X) # 匹配成功
re.U
(Unicode 模式):使\w
、\W
等元字符支持 Unicode 字符(如中文、日文等)。
修饰符使用方式:
- 在
re.match()
、re.findall()
等函数的最后一个参数指定,多个修饰符用|
连接(如re.M | re.I
)。