如何获取Requests模块发送给服务器的请求字节数据?
如何获取Requests模块发送给服务器的请求字节数据?
嗨,这个需求我之前也碰到过!其实requests内部是先把请求封装成PreparedRequest对象再发送的,我们可以利用这个机制来拿到最终要发送的字节数据,不用真的把请求发出去。
下面给你一步步来实现:
步骤1:构造并准备请求
先创建一个Request对象,然后调用prepare()方法生成PreparedRequest实例,这一步会自动处理好请求头、路径、请求体等所有细节:
import requests # 先构造基础的Request对象,指定请求方法和目标URL req = requests.Request('GET', 'http://example.com') # 执行请求准备操作,生成包含完整请求信息的PreparedRequest prepared_req = req.prepare()
步骤2:把PreparedRequest转换成标准HTTP请求字节
HTTP请求的格式是「请求行 + 请求头 + 空行 + 请求体」,我们需要按照这个规范把各个部分拼接成符合要求的字节串:
def get_request_bytes(prepared_request): # 拼接请求行:请求方法 + 请求路径 + HTTP协议版本 request_line = f"{prepared_request.method} {prepared_request.path_url} HTTP/1.1\r\n" # 拼接请求头:每个头字段以「键: 值\r\n」的形式组合 headers = ''.join(f"{k}: {v}\r\n" for k, v in prepared_request.headers.items()) # 空行用来分隔请求头和请求体 empty_line = "\r\n" # 获取请求体,没有的话就用空字节 body = prepared_request.body or b'' # 把字符串部分转成UTF-8编码的字节,再和请求体拼接 request_bytes = (request_line + headers + empty_line).encode('utf-8') # 处理请求体的类型:如果是字符串就转字节,已经是字节就直接用 if isinstance(body, str): request_bytes += body.encode('utf-8') else: request_bytes += body return request_bytes # 调用函数拿到最终的请求字节数据 request_bytes = get_request_bytes(prepared_req) print(request_bytes)
这样你得到的request_bytes就是和requests实际发送给服务器完全一致的字节串了,之后直接用Socket模块发送这个字节数据就可以啦~
另外要注意:如果是POST、PUT这类带请求体的请求,prepared_request.body可能已经是字节类型了,所以拼接的时候要做类型判断,避免重复编码出错。
备注:内容来源于stack exchange,提问作者Kucer0043




