iT邦幫忙

0

捕捉網頁超時的錯誤

我用python3的import requests中超時處理很好捕捉
resp=requests.get(url,timeout=10)
用except requests.exceptions.ReadTimeout:就能夠成功捕捉
但是另外一個import urllib.request
不知道為什麼都無法捕捉
resp = urllib.request.urlopen(url,timeout=10)
錯誤是說socket.timeout: timed out
但是用except socket.timeout:卻沒效果
變成except socket.timeout:
NameError: name 'socket' is not defined
有辦法捕捉這麻煩的錯誤嗎

雖然except:可以捕捉全部錯誤
但是我還有其他錯誤要分開處理...

1 個回答

0
listennn08
iT邦高手 7 級 ‧ 2020-06-05 08:38:03
最佳解答
from urllib.error import HTTPError, URLError

try:
    resp = urllib.request.urlopen(url,timeout=10)
except (HTTPError, URLError):
  print('timeout error')

要更進一步篩選確認是 http code error 還是 timeout error

from urllib.error import HTTPError, URLError
import socket

try:
    resp = urllib.request.urlopen(url,timeout=10)
except HTTPError as e:
    print('HTTP code error: %s %s' % (e.code, e.reason))
except URLError as error:
    if isinstance(error.reason, socket.timeout):
        print('socket timed out - URL %s', url)
s4028600 iT邦新手 5 級 ‧ 2020-06-05 22:26:58 檢舉

在測試的時候發現奇怪的狀況
我用的這個網址會出錯
會有無法捕捉的情況
我如果故意這樣resp = urllib.request.urlopen(url,timeout=0.1)
讓他沒時間
那就能成功捕捉
但是如果timeout=1
就會錯誤

Traceback (most recent call last):
  File "D:\long\Desktop\測試用.py", line 25, in <module>
    comic = get_record(url)
  File "D:\long\Desktop\測試用.py", line 16, in get_record
    resp = urllib.request.urlopen(url,timeout=1)
  File "C:\Program Files\Python37\lib\urllib\request.py", line 222, in urlopen
    return opener.open(url, data, timeout)
  File "C:\Program Files\Python37\lib\urllib\request.py", line 525, in open
    response = self._open(req, data)
  File "C:\Program Files\Python37\lib\urllib\request.py", line 543, in _open
    '_open', req)
  File "C:\Program Files\Python37\lib\urllib\request.py", line 503, in _call_chain
    result = func(*args)
  File "C:\Program Files\Python37\lib\urllib\request.py", line 1347, in http_open
    return self.do_open(http.client.HTTPConnection, req)
  File "C:\Program Files\Python37\lib\urllib\request.py", line 1322, in do_open
    r = h.getresponse()
  File "C:\Program Files\Python37\lib\http\client.py", line 1344, in getresponse
    response.begin()
  File "C:\Program Files\Python37\lib\http\client.py", line 306, in begin
    version, status, reason = self._read_status()
  File "C:\Program Files\Python37\lib\http\client.py", line 267, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "C:\Program Files\Python37\lib\socket.py", line 589, in readinto
    return self._sock.recv_into(b)
socket.timeout: timed out

所以原本還想說你提供的方法我之前試過也是失敗...
測試其他網址並沒有這個問題
是因為網址是json檔的關係嗎?

s4028600
有網址提供給我測試看看嗎
我是有測試一個網頁他會 return 403 不過直接訪問可以訪問

except socket.timeout as e:
    print('socket timeout')

這樣即可捕捉到你說的那個錯誤

我要發表回答

立即登入回答