Python请求在发送前查看

Python请求在发送前查看,python,python-requests,Python,Python Requests,在将请求发送到服务器之前,是否有人能提供查看我生成的请求的方法,以下是代码: import requests import urllib2 import logging from requests.packages.urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) url = "https://10.1.1.25

在将请求发送到服务器之前,是否有人能提供查看我生成的请求的方法,以下是代码:

import requests
import urllib2
import logging

from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

url = "https://10.1.1.254:4081/admin/api/jsonrpc/"
session = requests.Session()

data = {
    "jsonrpc": "2.0", "id": 1, "method": "Session.login",
    "params": {"userName": "test", "password":"test123"}
}
r = session.post(url, json=data, verify=False)

data = {"jsonrpc": "2.0", "id":3, "method":"Session.logout"}
r = session.post(url, json=data, verify=False)

因此,我希望在Python发送请求之前,使用session.post发送该请求。

这取决于“查看请求”的含义。 假设
session.post
的返回值是
requests.Response
,请检查

print(dir(requests.Response))

['__attrs__', '__bool__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__nonzero__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'apparent_encoding', 'close', 'content', 'is_permanent_redirect', 'is_redirect', 'iter_content', 'iter_lines', 'json', 'links', 'next', 'ok', 'raise_for_status', 'text']
也许您正在寻找的是
内容
json
,或者
文本
。 我不确定。 到目前为止,我无法测试它,因为我

TimeoutError: [WinError 10060] ...
你行吗

r = session.post(url, data_json, verify=False)

(我不确定这是否是因为我这里的连接不好)。

您想了解原始方法
如何请求.post()
处理您的输入数据,并将其转换为通过HTTP请求发送的数据包

如果查看,可以看到定义了两个对象,
Request()
,然后是
PreparedRequest()
(请参阅)。这些对象将为您提供所需的内容,您可以使用方法
prepare()
访问它们

请参见提供必要代码的部分:

>>> import requests
>>> req = requests.Request('POST','http://stackoverflow.com',headers={'X-Custom':'Test'},data='a=1&b=2')
>>> prepared = req.prepare()
>>> print(prepared.body, prepared.headers)
a=1&b=2 {'X-Custom': 'Test', 'Content-Length': '7'}

您不能使用高级助手函数来实现这一点。相反,您必须创建一个
request.PreparedRequest()
对象。通常你会实例化一个
request.request
对象(级别稍高),
prepare()
以获得
PreparedRequest
,然后你可以
session.send(req)

在发送之前,您可以从PrepareRequest中转储各种数据,我认为没有一种好的内置方法可以做到这一点,但在大多数情况下,HTTP适配器只会将请求的
方法
url
标题
正文
写入它打开的连接。因此,在发送之前打印这些文件应该是一个足够好的近似方法,可能需要一些格式


另一种方法是只在调试中配置httplib/urllib3/requests(不记得确切的名称),以便它自动打印请求/响应。

这里有三个选项:

  • 通过使用准备好的请求
  • 发送请求后检查请求
  • 您可以启用登录
    urlib3
    ,也可以在
    http.client
    库中启用调试
它们为您提供了不同级别的输出控制

准备好的请求 可以,这将为您提供一个新对象,其中所有数据都以最终形式设置。您可以查看属性的完整列表

下面是一个示例函数,它只是将数据格式化为通过网络发送的数据(除了它实际上不使用CRLF行分隔符,并用占位符字符串替换二进制内容):

对于示例请求,这将输出:

发送请求:
POST/admin/api/jsonrpc/HTTP/1.1
用户代理:python请求/2.22.0
接受编码:gzip,deflate
接受:*/*
连接:保持活力
内容长度:109
内容类型:application/json
{“jsonrpc”:“2.0”,“id”:1,“method”:“Session.login”,“params”:{“userName”:“test”,“password”:“test123”}
发送请求:
POST/admin/api/jsonrpc/HTTP/1.1
用户代理:python请求/2.22.0
接受编码:gzip,deflate
接受:*/*
连接:保持活力
内容长度:55
内容类型:application/json
{“jsonrpc”:“2.0”,“id”:3,“方法”:“Session.logout”}
发送请求后检查请求 响应对象引用了用于发出请求的准备好的请求对象,因此您可以在发送请求后打印该对象:

# ...
r = session.post(url, json=data, verify=False)
prepped = r.request
print("Request that was sent:")
print(format_prepped_request(prepped, 'utf8'))
print()
当然,这并不完全相同,请求现在已经发送了。另一方面,您不需要直接使用准备好的请求,
session.post()
完成了生成该对象本身的步骤

一定要考虑到,如果您的原始请求导致重定向,那么最终请求可能会有所不同。查看以访问前面的任何响应(每个响应都附有自己的请求)

登录中 使用,以及装配
http.client.HTTPConnection
类以将其调试输出记录到同一框架中,您也可以获得有关请求的调试级别信息。我在这里使用我的答案:

此时,您将在日志输出中看到请求:

DEBUG:http.client:send:b'POST/admin/api/jsonrpc/http/1.1\r\nHost:10.1.1.254:4081\r\n用户代理:python请求/2.22.0\r\n接受编码:gzip,deflate\r\n接受:/*\r\n连接:保持活动\r\n内容长度:109\r\n内容类型:application/json\r\n\r\r\n
调试:http.client:send:b'{“jsonrpc”:“2.0”,“id”:1,“method”:“Session.login”,“params”:{“userName”:“test”,“password”:“test123”}
调试:http。客户端:答复:“http/1.1 200正常\r\n”
调试:http.client:header:Date:Tue,04 Feb 2020 13:41:52 GMT
调试:http.client:header:Content-Type:application/json
调试:http.client:header:Content-Length:574
调试:http.client:header:Connection:keep-alive
调试:http.client:header:Server:gunicorn/19.9.0
调试:http。客户端:头:访问控制允许源:*
调试:http.client:头:访问控制允许凭据:true
调试:urllib3.connectionpool:https://10.1.1.254:4081 “POST/admin/api/jsonrpc/HTTP/1.1”200 574
调试:http.client:send:b'POST/admin/api/jsonrpc/http/1.1\r\nHost:10.1.1.254:4081\r\n用户代理:python请求/2.22.0\r\n接受编码:gzip,deflate\r\n接受:/*\r\n连接:保持活动\r\n内容长度:55\r\n内容类型:application/json\r\n\r\n
调试:http.client:send:b'{“jsonrpc”:“2.0”,“id”:3,“method”:“Session.logout”}”
调试:http。客户端:答复:“http/1.1 200正常\r\n”
调试:http.client:header:Date:Tue,04 Feb 2020 13:43:56 GMT
调试:http.client:header:Content-Type:application/json
调试:http.client:header:Content-Length:574
调试:http.client:header:Connection:keep-alive
调试:http.client:header:Server:gunicorn/19.9.0
调试:http。客户端:头:访问控制允许源:*
调试:http.client:h
url = "https://10.1.1.254:4081/admin/api/jsonrpc/"
session = requests.Session()

data = {
    "jsonrpc": "2.0", "id":1, "method": "Session.login",
    "params": {"userName": "test", "password":"test123"}
}

request = requests.Request('POST', url, json=data)
prepped = session.prepare_request(request)

print("Sending request:")
print(format_prepped_request(prepped, 'utf8'))
print()
r = session.send(prepped, verify=False)

data = {"jsonrpc": "2.0", "id":3, "method":"Session.logout"}
request = requests.Request('POST', url, json=data)
prepped = session.prepare_request(request)

print("Sending request:")
print(format_prepped_request(prepped, 'utf8'))
print()
r = session.send(prepped, verify=False)
# ...
r = session.post(url, json=data, verify=False)
prepped = r.request
print("Request that was sent:")
print(format_prepped_request(prepped, 'utf8'))
print()
import logging

# function definition from https://stackoverflow.com/a/16337639/100297
# configures http.client to log rather than print
httpclient_logging_patch()
logging.basicConfig(level=logging.DEBUG)