上一篇文章: Python3網絡爬蟲實戰---20、使用Urllib:發送請求
下一篇文章:
在前面一節咱們瞭解了 Request 的發送過程,可是在網絡狀況很差的狀況下,出現了異常怎麼辦呢?這時若是咱們不處理這些異常,程序極可能報錯而終止運行,因此異常處理仍是十分有必要的。html
Urllib 的 error 模塊定義了由 request 模塊產生的異常。若是出現了問題,request 模塊便會拋出 error 模塊中定義的異常,本節會對其進行詳細的介紹。nginx
URLError 類來自 Urllib 庫的 error 模塊,它繼承自 OSError 類,是 error 異常模塊的基類,由 request 模塊生的異常均可以經過捕獲這個類來處理。segmentfault
它具備一個屬性 reason,即返回錯誤的緣由。服務器
下面用一個實例來感覺一下:網絡
from urllib import request, error try: response = request.urlopen('http://cuiqingcai.com/index.htm') except error.URLError as e: print(e.reason)
咱們打開一個不存在的頁面,照理來講應該會報錯,可是這時咱們捕獲了 URLError 這個異常,運行結果以下:socket
Not Found
程序沒有直接報錯,而是輸出瞭如上內容,這樣經過如上操做,咱們就能夠避免程序異常終止,同時異常獲得了有效處理。ui
它是 URLError 的子類,專門用來處理 HTTP 請求錯誤,好比認證請求失敗等等。url
它有三個屬性。code
下面咱們來用幾個實例感覺一下:htm
from urllib import request,error try: response = request.urlopen('http://cuiqingcai.com/index.htm') except error.HTTPError as e: print(e.reason, e.code, e.headers, sep='\n')
運行結果:
Not Found 404 Date: Mon, 17 Jun 2019 04:52:50 GMT Content-Type: text/html; charset=utf-8 Transfer-Encoding: chunked Connection: close Vary: Accept-Encoding Status: 404 Not Found Cache-Control: no-cache Strict-Transport-Security: max-age=31536000 X-XSS-Protection: 1; mode=block X-Request-Id: e65fb029-a4fd-46e2-91c3-9616ccc2f879 X-Runtime: 0.006814 X-Frame-Options: SAMEORIGIN X-Content-Type-Options: nosniff X-Powered-By: Phusion Passenger 6.0.2 Server: nginx + Phusion Passenger 6.0.2
依然是一樣的網址,在這裏咱們捕獲了 HTTPError 異常,輸出了 reason、code、headers 屬性。
由於 URLError 是 HTTPError 的父類,因此咱們能夠先選擇捕獲子類的錯誤,再去捕獲父類的錯誤,因此上述代碼更好的寫法以下:
from urllib import request, error try: response = request.urlopen('http://cuiqingcai.com/index.htm') except error.HTTPError as e: print(e.reason, e.code, e.headers, sep='\n') except error.URLError as e: print(e.reason) else: print('Request Successfully')
這樣咱們就能夠作到先捕獲 HTTPError,獲取它的錯誤狀態碼、緣由、Headers 等詳細信息。若是非 HTTPError,再捕獲 URLError 異常,輸出錯誤緣由。最後用 else 來處理正常的邏輯,這是一個較好的異常處理寫法。
有時候 reason 屬性返回的不必定是字符串,也多是一個對象,咱們再看下面的實例:
import socket import urllib.request import urllib.error try: response = urllib.request.urlopen('https://www.baidu.com', timeout=0.01) except urllib.error.URLError as e: print(type(e.reason)) if isinstance(e.reason, socket.timeout): print('TIME OUT')
在這裏咱們直接設置了超時時間來強制拋出 timeout 異常。
運行結果以下:
<class 'socket.timeout'> TIME OUT
能夠發現 reason 屬性的結果是 socket.timeout 類。因此在這裏咱們能夠用 isinstance() 方法來判斷它的類型,作出更詳細的異常判斷。
本節講述了 error 模塊的相關用法,經過合理地捕獲異常能夠作出更準確的異常判斷,使得程序更佳穩健。