如何在 Python 中重放 HTTP 请求

问题描述 投票:0回答:1

我想在 python 中重播任意原始 HTTP 请求。 例如,让我们使用从我的 Chromium 浏览器到 Google 的任意 GET 请求:

GET / HTTP/1.1
Host: google.de
Cookie: CONSENT=PENDING+071; AEC=ARSKqsKvfEvPS9Vp1bDM6YMPdHpVOoH357W-7q3cqtdDwYeHf3MqPEO1xA; SOCS=CAISHAgBEhJnd3NfMjAyMzAyMjMtMF9SQzEaAmRlIAEaBgiAn-WfBg; NID=511=N6YvXcWd_hnVVnV8w6JK4jscqE2pEt8MuTrw3yZJp-84ZxV6RJLee_yj2DEo2UJuOse0sqLjdnAD7qgPw9al7aEJqsQOCAQPIs21rLy5HQ5IAoObj7icI7ayKJttejI9Va2jDFkk0ZLvUC7P_VPJuxRJyhvLspqU1YVUcYCThrYizbo; 1P_JAR=2023-2-25-20
Sec-Ch-Ua: "Not A(Brand";v="24", "Chromium";v="110"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.78 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
X-Client-Data: CO3/ygE=
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close

因为我希望我的请求看起来与上面完全一样,一个明显的方法是使用套接字库:

def send(host, port, message):
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.connect((host, port))
        s.sendall(message)
        print("%s" % message.decode('us-ascii'))
        data = s.recv(1024)

    print("%s" % data)

但是,那样的话,我显然不能使用 TLS 或代理(不编写我自己的库)。

所以,我认为请求库值得一试,因为它已经支持开箱即用的 TLS 和代理。但是我不知道如何加载我想重播的 HTTP 请求。 我想图书馆不是为此而设计的。

我可以尝试这样的事情(来自文档):

from requests import Request, Session

s = Session()

req = Request('POST', url, data=data, headers=headers)
prepped = req.prepare()

# do something with prepped.body
prepped.body = 'No, I want exactly this as the body.'

# do something with prepped.headers
del prepped.headers['Content-Type']

resp = s.send(prepped,
    stream=stream,
    verify=verify,
    proxies=proxies,
    cert=cert,
    timeout=timeout
)

print(resp.status_code)

但我仍然必须首先手动解析请求的标头。 如果有图书馆可以解决这个问题?

感谢您的参与!

python http replay
1个回答
0
投票

TLS 可以与套接字一起使用;你只需要将它包裹在

ssl
库套接字中。

但是,有 很多 库可以做到这一点,所以你不必自己使用 TLS。

您可以使用 aioreq 库,这是一个简单的异步 HTTP 客户端,可用于发送原始 HTTP 请求消息。

Aioreq
不支持原始请求的代理,但它确实允许您做很多有趣的事情,看看 HTTP 协议是如何工作的。

这是你的要求(没有

Cookie
标题,它很大:D)。

import asyncio
import aioreq
import socket

async def main():
    hostname = "google.de"
    transport = aioreq.Transport()
    await transport.make_connection(
        ip=socket.gethostbyname(hostname),
        port=443,
        ssl=True,  # True if you want to use SSL/TLS
        server_hostname=hostname
    )

    raw_request_bytes = ("GET / HTTP/1.1\r\n"
"Host: google.de\r\n"
'Sec-Ch-Ua: "Not A(Brand";v="24", "Chromium";v="110"\r\n'
"Sec-Ch-Ua-Mobile: ?0\r\n"
'Sec-Ch-Ua-Platform: "Linux"\r\n'
"Upgrade-Insecure-Requests: 1\r\n"
"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                         "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.78 Safari/537.36\r\n"
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,'
                         'image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7\r\n'
"X-Client-Data: CO3/ygE=\r\n"
"Sec-Fetch-Site: none\r\n"
"Sec-Fetch-Mode: navigate\r\n"
"Sec-Fetch-User: ?1\r\n"
"Sec-Fetch-Dest: document\r\n"
"Accept-Encoding: gzip, deflate\r\n"
"Accept-Language: en-US,en;q=0.9\r\n"
"Connection: close\r\n\r\n"
).encode("ascii")

    status_line, headers_line, content = await transport.send_http_request(
        raw_request_bytes
    )
    resp = aioreq.parsers.ResponseParser.parse(status_line, headers_line, content)
    print(resp)
asyncio.run(main())

因此,我们有变量

resp
,这是我们的 HTTP 响应及其所有必需的属性,例如(.headers,.content,.status,...)

© www.soinside.com 2019 - 2024. All rights reserved.