Skip to main content
 首页 » 编程设计

python之urllib HTTPError 没有被 Python/Django 捕获

2025年02月15日22lori

我正在尝试使用 urllib 处理 HTTPError。 我的设置是使用 Django 1.10 的 anaconda virtualenv 中的 python3。 当代码得到尝试时,它不会进入 except 并使我的页面崩溃,Django 告诉我有一个 HTTP 错误。

代码如下:

from urllib.request import Request, urlopen 
from urllib.error import URLError, HTTPError 
 
try: 
  req = Request(api.lists.members.get(LIST_ID, client_email)) 
  response = urlopen(req) 
except HTTPError as e: 
  print('Error code: ', e.code) 
else: 
  print('everything is fine') 

回溯:

环境:

Request Method: POST 
Request URL: http://127.0.0.1:8000/homepage/ 
 
Django Version: 1.10 
Python Version: 3.6.1 
Installed Applications: 
['django.contrib.admin', 
 'django.contrib.auth', 
 'django.contrib.contenttypes', 
 'django.contrib.sessions', 
 'django.contrib.messages', 
 'django.contrib.staticfiles', 
 'website'] 
Installed Middleware: 
['django.middleware.security.SecurityMiddleware', 
 'django.contrib.sessions.middleware.SessionMiddleware', 
 'django.middleware.common.CommonMiddleware', 
 'django.middleware.csrf.CsrfViewMiddleware', 
 'django.contrib.auth.middleware.AuthenticationMiddleware', 
 'django.contrib.messages.middleware.MessageMiddleware', 
 'django.middleware.clickjacking.XFrameOptionsMiddleware'] 
 
 
 
Traceback: 
 
File "/Users/plfiras/anaconda/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner 
  39.             response = get_response(request) 
 
File "/Users/plfiras/anaconda/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response 
  187.                 response = self.process_exception_by_middleware(e, request) 
 
File "/Users/plfiras/anaconda/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response 
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs) 
 
File "/Users/plfiras/vinhood/vinhood-website/website/views.py" in homepage 
  52.             conn = http.client.HTTPConnection(api.lists.members.get(LIST_ID, client_email)) 
 
File "/Users/plfiras/anaconda/lib/python3.6/site-packages/mailchimp3/entities/listmembers.py" in get 
  116.         return self._mc_client._get(url=self._build_path(list_id, 'members', subscriber_hash), **queryparams) 
 
File "/Users/plfiras/anaconda/lib/python3.6/site-packages/mailchimp3/mailchimpclient.py" in wrapper 
  25.             return fn(self, *args, **kwargs) 
 
File "/Users/plfiras/anaconda/lib/python3.6/site-packages/mailchimp3/mailchimpclient.py" in _get 
  100.             r.raise_for_status() 
 
File "/Users/plfiras/anaconda/lib/python3.6/site-packages/requests/models.py" in raise_for_status 
  928.             raise HTTPError(http_error_msg, response=self) 
 
Exception Type: HTTPError at /homepage/ 
Exception Value: 404 Client Error: Not Found for url: https://us13.api.mailchimp.com/3.0/lists/7bdb42e5c9/members/d071e758df3554f0fe89679212ef95e8 

请您参考如下方法:

您捕捉到了错误的异常。查看回溯的最后一行:

 File "/Users/plfiras/anaconda/lib/python3.6/site-packages/requests/models.py" in raise_for_status 
  928.  raise HTTPError(http_error_msg, response=self) 

看看 requests/models.py 的第 31 行你会看到以下内容:

from .exceptions import ( 
HTTPError, MissingSchema, InvalidURL, ChunkedEncodingError, 
ContentDecodingError, ConnectionError, StreamConsumedError) 

如您所见,引发的 HTTPError 实际上来自 requests/exceptions.py .查看文件顶部,您会看到:

from urllib3.exceptions import HTTPError as BaseHTTPError 
 
 
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 HTTPError(RequestException): 
    """An HTTP error occurred.""" 

这表明 HTTPError 被导入为 BaseHTTPError,并且请求库实现了它自己的 HTTPError,它不扩展 urlib3.HTTPError。

所以要捕获错误,您需要从请求模块导入 HTTPError,而不是 urlib,如下所示:

from requests.exceptions import HTTPError 
 
try: 
  req = Request(api.lists.members.get(LIST_ID, client_email)) 
  response = urlopen(req) 
except HTTPError as e: 
  print('Error code: ', e.code) 
else: 
  print('everything is fine')