如何在Python 3中处理urllib的超时?

nin*_*alf 21 python exception urllib

首先,我的问题与问题非常相似.我希望urllib.urlopen()超时以生成我可以处理的异常.

这不属于URLError吗?

try:
    response = urllib.request.urlopen(url, timeout=10).read().decode('utf-8')
except (HTTPError, URLError) as error:
    logging.error(
        'Data of %s not retrieved because %s\nURL: %s', name, error, url)
else:
    logging.info('Access successful.')
Run Code Online (Sandbox Code Playgroud)

错误消息:

resp = urllib.request.urlopen(req,timeout = 10).read().decode('utf-8')
File"/usr/lib/python3.2/urllib/request.py",第138行,在urlopen中
return opener.open(url,data,timeout)
文件"/usr/lib/python3.2/urllib/request.py",第369行,打开
响应= self._open(req,data)
文件"/ usr/lib /python3.2/urllib/request.py",第387 行,在_open'_open
',req中)
文件"/usr/lib/python3.2/urllib/request.py",第347行,在_call_chain
result = func(*args)
文件"/usr/lib/python3.2/urllib/request.py",第1156行,在http_open中
返回self.do_open(http.client.HTTPConnection,req)
文件"/usr/lib/python3.2/ urllib/request.py",第1141行,在
do_open 中r = h.getresponse()
文件"/usr/lib/python3.2/http/client.py",第1046行,在getresponse
response.begin()
文件中"/ usr/lib/python3.2/http/client.py",第346行,在开始
版本,状态,原因= self._read_status()
文件"/usr/lib/python3.2/http/client.py",行308,在_read_status
line = str(self.fp.readline(_MAXLINE + 1),"iso-8859-1")
文件"/usr/lib/python3.2/socket.py ",第276行,在readinto中
返回self._sock.recv_into(b)socket.timeout
:超时

当Python 3重新组织urlliburllib2模块时,Python 3发生了重大变化urllib.是否有可能导致这种情况发生变化?

dan*_*van 30

例外是socket的超时,所以

from socket import timeout
try:
    response = urllib.request.urlopen(url, timeout=10).read().decode('utf-8')
except (HTTPError, URLError) as error:
    logging.error('Data of %s not retrieved because %s\nURL: %s', name, error, url)
except timeout:
    logging.error('socket timed out - URL %s', url)
else:
    logging.info('Access successful.')
Run Code Online (Sandbox Code Playgroud)

应该抓住新的例外.

  • 这是绝对错误的!在 Python 3.9 中,仅捕获第一个异常。也许 3 到 3.9 之间引入了一些更改? (2认同)

Rég*_* B. 7

上一个答案没有正确拦截超时错误.引发超时错误URLError,因此如果我们想要专门捕获它们,我们需要写:

from urllib.error import HTTPError, URLError
import socket

try:
    response = urllib.request.urlopen(url, timeout=10).read().decode('utf-8')
except HTTPError as error:
    logging.error('Data not retrieved because %s\nURL: %s', error, url)
except URLError as error:
    if isinstance(error.reason, socket.timeout):
        logging.error('socket timed out - URL %s', url)
    else:
        logging.error('some other error happened)
else:
    logging.info('Access successful.')
Run Code Online (Sandbox Code Playgroud)

请注意,ValueError可以单独引发,即URL无效.比如HTTPError,它与超时无关.

  • 尽管有这段代码,我曾经遇到过“socket.timeout”异常。它没有被这段代码捕获。在多次尝试中,这种情况只发生过一次。该代码在大多数情况下都是正确的,尽管捕获“URLError”会捕获*大多数*超时错误。这是 Python 3.7.2 的情况。**总之,为了更安全,我还捕获了`socket.timeout`**。 (3认同)