python requests/urllib3连接池未捕获HTTP错误。
python requests/urllib3连接池未捕获HTTP错误。
使用连接池的python requests(urllib3)无法捕捉http错误。这是一个bug吗?还是我做错了什么?\n
#!/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
\n输出:\n
$ ./test.py https://github.com success$ ./test.py https://github.com/sithlordyoyoma success
\n我本来期望得到HTTPError。我做错了什么吗?\n我从这个线程中获得了contextlib的关闭方法should I call close() after urllib.urlopen()?。这是根据Alex Martelli的建议。\n实际上,不使用连接的requests也显示了这种行为\n
#!/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
\n输出:\n
$ ./test.py https://github.com success$ ./test.py https://github.com/sithlordyoyoma success
\nurllib2可以正确处理这个问题\n
#!/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
\n输出:\n
$ ./test.py https://github.com success> $ ./test.py https://github.com/sithlordyoyoma HTTPError HTTPError()
无论是否使用连接池,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()
唉,看了文档,明白了。我原本期望的行为类似于urllib2。这就是困惑的根源。 docs.python-requests.org/en/latest/api/…
问题的原因是使用requests.post
方法时,无论是否使用连接池,在遇到404错误时都不会引发HTTPError
异常,这与urllib2的行为不同,导致了混淆。
解决方法是,在使用requests.post
方法后调用.raise_for_status()
方法,以便在遇到HTTP错误时引发HTTPError
异常。
这篇文章指出了使用requests.post
方法时的一个问题:无论是否使用连接池,在遇到404错误时都不会引发HTTPError
异常。然后提供了解决方法,即在调用requests.post
方法后调用.raise_for_status()
方法。