【Python3網絡爬蟲開發實戰】3-基本庫的使用 1.2-處理異常

前一節咱們瞭解了請求的發送過程,可是在網絡很差的狀況下,若是出現了異常,該怎麼辦呢?這時若是不處理這些異常,程序極可能因報錯而終止運行,因此異常處理仍是十分有必要的。html

urllib的error模塊定義了由request模塊產生的異常。若是出現了問題,request模塊便會拋出error模塊中定義的異常。nginx

1. URLError

URLError類來自urllib庫的error模塊,它繼承自OSError類,是error異常模塊的基類,由request模塊生的異常均可以經過捕獲這個類來處理。json

它具備一個屬性reason,即返回錯誤的緣由。ubuntu

下面用一個實例來看一下:api

from urllib import request, error
try:
    response = request.urlopen('http://cuiqingcai.com/index.htm')
except error.URLError as e:
    print(e.reason)
複製代碼

咱們打開一個不存在的頁面,照理來講應該會報錯,可是這時咱們捕獲了URLError這個異常,運行結果以下:bash

Not Found
複製代碼

程序沒有直接報錯,而是輸出瞭如上內容,這樣經過如上操做,咱們就能夠避免程序異常終止,同時異常獲得了有效處理。服務器

2. HTTPError

它是URLError的子類,專門用來處理HTTP請求錯誤,好比認證請求失敗等。它有以下3個屬性。微信

  • code:返回HTTP狀態碼,好比404表示網頁不存在,500表示服務器內部錯誤等。
  • reason:同父類同樣,用於返回錯誤的緣由。
  • headers:返回請求頭。

下面咱們用幾個實例來看看:網絡

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, seq='\n')
複製代碼

運行結果以下:socket

Not Found
404
Server: nginx/1.4.6 (Ubuntu)
Date: Wed, 03 Aug 2016 08:54:22 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: close
X-Powered-By: PHP/5.5.9-1ubuntu4.14
Vary: Cookie
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
Pragma: no-cache
Link: <http://cuiqingcai.com/wp-json/>; rel="https://api.w.org/"
複製代碼

依然是一樣的網址,這裏捕獲了HTTPError異常,輸出了reasoncodeheaders屬性。

由於URLErrorHTTPError的父類,因此能夠先選擇捕獲子類的錯誤,再去捕獲父類的錯誤,因此上述代碼更好的寫法以下:

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模塊的相關用法,經過合理地捕獲異常能夠作出更準確的異常判斷,使程序更加穩健。


本資源首發於崔慶才的我的博客靜覓: Python3網絡爬蟲開發實戰教程 | 靜覓

如想了解更多爬蟲資訊,請關注個人我的微信公衆號:進擊的Coder

weixin.qq.com/r/5zsjOyvEZ… (二維碼自動識別)

相關文章
相關標籤/搜索