当请求抛出异常时,如何从请求中获取响应对象?
本质上,我正在尝试通过代理发出请求,并且代理正在返回302代码(这是我想要的)。但是,在进行一些调试之后,我发现在requests
库中,它期望来自代理的200条代码,否则将引发异常。
这是我正在执行的命令:
session.get(url=url, headers=req_headers, verify=False, allow_redirects=True, timeout=30)
这给了我(Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 302 Object Moved'))
。这是我期望从代理获得的正确行为,但是我需要响应对象,因为响应对象具有逻辑中需要的有用信息,现在我只能得到错误消息。有没有办法我仍然可以获取响应对象而不必修改requests
库?
感谢您的帮助!
编辑:
def _tunnel(self):
connect_str = "CONNECT %s:%d HTTP/1.0\r\n" % (self._tunnel_host,
self._tunnel_port)
connect_bytes = connect_str.encode("ascii")
self.send(connect_bytes)
for header, value in self._tunnel_headers.items():
header_str = "%s: %s\r\n" % (header, value)
header_bytes = header_str.encode("latin-1")
self.send(header_bytes)
self.send(b'\r\n')
response = self.response_class(self.sock, method=self._method)
(version, code, message) = response._read_status()
if code != http.HTTPStatus.OK:
self.close()
raise OSError("Tunnel connection failed: %d %s" % (code,
message.strip()))
我已对其进行调试,以使我知道代码正在引发OSError,并且仅提供状态代码和消息。我想做的就是也将response
传递给该异常,但是同时我不想更改该库,因为我希望有一种方法可以在不更改lib的情况下
答案 0 :(得分:1)
从源代码看,Requests中的ProxyError异常对象看起来像该对象中应该包含请求。我知道您说过您认为不行,但这表明它至少要在其中放置一个response
字段,即使该字段最终以null
结尾。
我可能会将其放在注释中,但是您无法在此处格式化代码。这种确定似乎可以给您想要的东西,
class RequestException(IOError):
"""There was an ambiguous exception that occurred while handling your
request.
"""
def __init__(self, *args, **kwargs):
"""Initialize RequestException with `request` and `response` objects."""
response = kwargs.pop('response', None)
self.response = response
self.request = kwargs.pop('request', None)
if (response is not None and not self.request and
hasattr(response, 'request')):
self.request = self.response.request
super(RequestException, self).__init__(*args, **kwargs)
class ConnectionError(RequestException):
"""A Connection error occurred."""
class ProxyError(ConnectionError):
"""A proxy error occurred."""
因此,看到此代码,似乎可以进行以下操作:
try:
...
session.get(url=url, headers=req_headers, verify=False, allow_redirects=True, timeout=30)
...
except ProxyError as ex:
the_response = ex.response
.. do something with the response ..
答案 1 :(得分:0)
我认为您也许可以使用Request的history
功能访问该对象,然后使用Request的标准API:
https://2.python-requests.org//en/latest/user/quickstart/#redirection-and-history
默认情况下,请求将对所有动词执行位置重定向 除了HEAD。
我们可以使用Response对象的history属性来跟踪 重定向。
Response.history列表包含以下响应对象: 创建以完成请求。该列表从 从最早到最新的响应。
r = requests.get('http://github.com/')
r.url 'https://github.com/'
r.status_code 200
r.history [<Response [301]>]
headers
会不给您您所需要的吗?
https://2.python-requests.org//en/latest/user/advanced/#advanced
>>> r.headers
{'content-length': '56170', 'x-content-type-options': 'nosniff', 'x-cache':
'HIT from cp1006.eqiad.wmnet, MISS from cp1010.eqiad.wmnet', 'content-encoding':
'gzip', 'age': '3080', 'content-language': 'en', 'vary': 'Accept-Encoding,Cookie',
'server': 'Apache', 'last-modified': 'Wed, 13 Jun 2012 01:33:50 GMT',
'connection': 'close', 'cache-control': 'private, s-maxage=0, max-age=0,
must-revalidate', 'date': 'Thu, 14 Jun 2012 12:59:39 GMT', 'content-type':
'text/html; charset=UTF-8', 'x-cache-lookup': 'HIT from cp1006.eqiad.wmnet:3128,
MISS from cp1010.eqiad.wmnet:80'}