Tout d'abord, mon problème est assez similaire à celui-ci . Je voudrais un délai d'expiration de urllib.urlopen () pour générer une exception que je peux gérer.
Cela ne relève-t-il pas d'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.')
Le message d'erreur:
resp = urllib.request.urlopen (req, timeout = 10) .read (). decode ('utf-8')
Fichier "/usr/lib/python3.2/urllib/request.py", ligne 138, dans urlopen
return opener.open (url, data, timeout)
Fichier "/usr/lib/python3.2/urllib/request.py", ligne 369, en ouvert
response = self._open (req, data)
Fichier "/usr/lib/python3.2/urllib/request.py", ligne 387, dans _open
'_ open', req)
Fichier "/usr/lib/python3.2/urllib/request.py", ligne 347, dans _call_chain
result = func (* args)
Fichier "/usr/lib/python3.2/urllib/request.py", ligne 1156, dans http_open
return self.do_open (http.client.HTTPConnection, req)
Fichier "/usr/lib/python3.2/urllib/request.py", ligne 1141, dans do_open
r = h.getresponse ()
Fichier "/usr/lib/python3.2/http/client.py", ligne 1046, dans getresponse
response.begin ()
Fichier "/usr/lib/python3.2/http/client.py", ligne 346, au début
version, statut, raison = self._read_status ()
Fichier "/usr/lib/python3.2/http/client.py", ligne 308, dans _read_status
line = str (self.fp.readline (_MAXLINE + 1), "iso-8859-1")
Fichier "/usr/lib/python3.2/socket.py", ligne 276, en lecture dans
return self._sock.recv_into (b)
socket.timeout: expiration
Il y a eu un changement majeur par rapport à Python 3 quand ils ont réorganisé les urllib
et urllib2
modules dans urllib
. Est-il possible qu'il y ait eu alors un changement qui provoque cela?
L'exception est le délai d'expiration du socket, donc
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.')
devrait attraper la nouvelle exception.
La réponse précédente n'intercepte pas correctement les erreurs de délai d'attente. Les erreurs de timeout sont déclenchées comme URLError
, donc si nous voulons les attraper spécifiquement, nous devons écrire:
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.')
Notez que ValueError
peut être augmenté indépendamment, c'est-à-dire si l'URL n'est pas valide. Comme HTTPError
, il n'est pas associé à un timeout.