如何在抛出异常时从Requests GET调用获取响应对象

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

如何在抛出异常时从请求中获取响应对象?

本质上,我正在尝试通过代理发出请求,代理正在返回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的情况下执行此操作

python python-requests
2个回答
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 ..

0
投票

我认为您可以使用Request的history功能来访问该对象,并且可以使用Request的标准API:

https://2.python-requests.org//en/latest/user/quickstart/#redirection-and-history

默认情况下,Requests将为除HEAD之外的所有动词执行位置重定向。

我们可以使用Response对象的history属性来跟踪重定向。

Response.history列表包含为完成请求而创建的Response对象。该列表从最旧的响应到最新的响应排序。

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'}
© www.soinside.com 2019 - 2024. All rights reserved.