You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何获取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

火山引擎 最新活动