【问题标题】:python requests/urllib3 connection pooling not catching HTTP errorspython 请求/urllib3 连接池未捕获 HTTP 错误
【发布时间】:2016-02-14 10:40:12
【问题描述】:

带有连接池的 python 请求 (urllib3) 没有捕获 http 错误。这是一个错误吗?还是我做错了什么?

#!/usr/bin/env python

import contextlib
import requests
import sys

connection_pool_size = 2
adapter = requests.adapters.HTTPAdapter(pool_connections=connection_pool_size,
                                        pool_maxsize=connection_pool_size)
r_session = requests.Session()
r_session.mount('http', adapter)

try:
    with contextlib.closing(r_session.get(sys.argv[1], timeout=30, allow_redirects=True)) as r:
        print 'success %r' % r
except requests.exceptions.HTTPError as e:
    print 'HTTPError %r' % e
except Exception as e:
    print 'Exception %r' % e

输出:

$ ./test.py https://github.com
success <Response [200]>
$ ./test.py https://github.com/sithlordyoyoma
success <Response [404]>

我期待 HTTPError 。我做错了吗?

我从这个线程 should I call close() after urllib.urlopen()? 得到的 contextlib 结束。正如 Alex Martelli 所建议的那样。

在没有连接的情况下实际运行的请求也显示此行为

#!/usr/bin/env python

import contextlib
import requests
import sys


try:
    with contextlib.closing(requests.get(sys.argv[1], timeout=30, allow_redirects=True)) as r:
        print 'success %r' % r
except requests.exceptions.HTTPError as e:
    print 'HTTPError %r' % e
except Exception as e:
    print 'Exception %r' % e

输出:

$ ./test.py https://github.com
success <Response [200]>
$ ./test.py https://github.com/sithlordyoyoma
success <Response [404]>

urllib2 正确地做到了这一点

#!/usr/bin/env python

import contextlib
import urllib2
import sys


try:
    with contextlib.closing(urllib2.urlopen(sys.argv[1], timeout=30)) as r:
        print 'success %r' % r
except urllib2.HTTPError as e:
    print 'HTTPError %r' % e
except Exception as e:
    print 'Exception %r' % e

输出:

$ ./test.py https://github.com
success <addinfourl at 4338734792 whose fp = <socket._fileobject object at 0x1025a5c50>>
$ ./test.py https://github.com/sithlordyoyoma
HTTPError HTTPError()

【问题讨论】:

  • Response.raise_for_status() 可能有帮助吗?不是答案,因为当您应该必须使用它时,我不了解自己。
  • 你为什么期待HTTPError
  • 404 不是 HTTPError 吗?我也在用 404 进行演示。但这发生在 400、502 和 503 上。到目前为止我注意到的那些。
  • 我刚刚更新了一些更改和更多示例,我使用 POST 而不是该 URL 的 GET 进行演示。另外我认为这只是通过连接池。我也可以看到在使用常规请求时会发生这种情况。

标签: python python-requests urllib3


【解决方案1】:

不管连接池如何,requests.post(和其他 HTTP 方法)都不会在 404 上引发 HTTPErrorHTTPError 是通过调用 .raise_for_status() 引发的,如下例所示:

#!/usr/bin/env python

import requests

r = requests.post(
    'https://github.com/sithlordyoyoma',
    timeout=30,
    allow_redirects=True
)
print 'success %r' % r
r.raise_for_status()

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
  • 2012-02-18
  • 2017-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多