python requests / urllib3连接池没有捕获HTTP错误

时间:2015-11-12 22:36:40

标签: python python-requests urllib3

带连接池的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。我做错了吗?

关闭contextlib,我从这个帖子should I call close() after urllib.urlopen()?得到了。正如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()

1 个答案:

答案 0 :(得分:1)

无论连接池如何,requests.post(以及其他HTTP方法)都不会在404上引发HTTPError。通过调用HTTPError引发.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()
相关问题