【Python3 爬蟲學習筆記】基本庫的使用 1
一、使用urllib
在Python 2中,有urllib和urllib2兩個庫來實現請求的傳送。而在Python 3中,已經不存在urllib2這個庫,統一為urllib。 urllib庫是Python內建的HTTP請求庫,不需要額外安裝,包含如下四個模組:
- request:它是最基本的HTTP請求模組,可以用來模擬傳送請求。就像在瀏覽器裡輸入網址然後回車一樣,只需要給庫方法傳入URL以及額外的引數,就可以模擬實現這個過程。
- error:異常處理模組,如果出現請求錯誤,我們可以捕獲這些異常,然後進行重試或其他操作以保證程式不會意外終止。
- parse:一個工具模組,提供了許多URL處理方法,比如拆分、解析、合併等。
- robotparser:主要是用來識別網站的robots.txt檔案,然後判斷哪些網站可以爬,哪些網站不可以爬,它其實用得比較少。
1. 傳送請求
使用urllib的request模組,可以方便地實現請求的傳送並得到響應。
1.1 urlopen()
urllib.request模組提供了最基本的構造HTTP請求的方法,利用它可以模擬瀏覽器的一個請求發起過程,同時它還帶有處理授權驗證(authenticaton)、重定向(redirection)、瀏覽器Cookies以及其他內容。
import urllib.request
response = urllib.request.urlopen('https://www.python.org' )
print(response.read().decode('utf-8'))
可以檢視返回內容。
print(type(response))
//輸出結果如下:
<class 'http.client.HTTPResponse'>
呼叫read()方法可以得到返回的網頁內容,呼叫status屬性可以得到返回結果的狀態碼,如200代表請求成功,404代表網頁未找到。
print(response.status)
print(response.getheaders())
print(response.getheader('Server'))
執行結果如下:
可見,前兩個輸出分別輸出了響應的狀態碼和響應的頭資訊,最後一個輸出通過條用getheader()方法並傳遞一個引數Server獲取了響應頭中的Server值,結果是nginx,意思是伺服器是用Nginx搭建的。 利用最基本的urlopen()方法,可以完成最基本的簡單頁面的GET請求抓取。還能更深入的輸入一些引數,urlopen()函式的API:
urllib.request.urlopen(url,data=None,[timeout,]*,cafile=None,capath=None,cadefault=False,context=None)
- data引數 data引數是可選的。如果要新增該引數,並且如果它是位元組流編碼格式的內容,即bytes型別,則需要通過bytes()方法轉化。另外,如果傳遞了這個引數,則它的請求方式就不再是GET方式,而是POST方式。
- timeout引數 timeout引數用於設定超時時間,單位為妙,意思是如果請求超出了設定的這個時間,還沒有得到響應,就會丟擲異常。如果不指定該引數,就會使用全域性預設時間。它支援HTTP、HTTPS、FTP請求。
- 其他引數 除了data引數和timeout引數外,還有context引數,它必須是ssl.SSLContext型別,用來指定SSL設定。 此外,cafile和capath這兩個引數分別指定CA證書和它的路徑,這個請求HTTPS連結時會有用。 cadefault引數現在已經棄用了,其預設值為False。
1.2 Request
利用urlopen()方法可以實現最基本請求的發起,但這幾個簡單的引數並不足以構建一個完整的請求。如果請求中需要加入Headers等資訊,就可以利用更強大的Request類來構建。 Request的構造方法:
class urllib.request.Request(url,data=None,headers={},origin_req_host=None,unverifiable=False,method=None)
- 第一個引數url用於請求URL,這是必傳引數,其他都是可選引數。
- 第二個引數data如果要傳,必須傳bytes(位元組流)型別的。如果它是字典,可以先用urllib.parse模組裡的urlencode()編碼。
- 第三個引數headers是一個字典,它就是請求頭,可以在構造請求時通過headers引數直接構造,也可以通過呼叫請求例項的add_header()方法新增。 新增請求頭最常用的用法就是通過修改User-Agent來偽裝瀏覽器,預設的User-Agent是Python-urllib,我們可以通過修改它來偽裝瀏覽器。比如要偽裝火狐瀏覽器,可以把它設定為:
Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11
- 第四個引數origin_req_host指的是請求方的host名稱或者IP地址。
- 第五個引數unverifiable表示這個請求是否是無法驗證的,預設是Flase,意思就是說使用者沒有足夠許可權來選擇接收這個請求的結果。例如,我們請求一個HTML文件中的圖片,但是我們沒有自動抓取影象的許可權,這時unverifiable的值就是True。
- 第六個引數method是一個字串,用來指示請求使用的方法,比如GET、POST和PUT等。
傳入多個引數構建請求的例子:
from urllib import request,parse
url = 'http://httpbin.org/post'
headers = {
'User-Agent':'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
'Host':'httpbin.org'
}
dict = {'name':'Germey'}
data = bytes(parse.urlencode(dict),encoding='utf8')
req = request.Request(url=url, data=data, headers=headers, method='POST')
response = request.urlopen(req)
print(response.read().decode('utf-8'))
通過4個引數構建了一個請求,其中url即請求URL,headers中指定了User-Agent和Host,引數data用urlencode()和bytes()方法轉成位元組流。另外,指定了請求方式為POST。 執行結果如下:
另外,headers也可以用add_header()方法來新增:
req = request.Request(url=url,data=data,method='POST')
req.add_header('User-Agent','Mozilla/4.0 (compatible;MSIE 5.5;Windows NT)')
1.3 高階用法
urllib.request模組裡的BaseHandler類,是所有其他Handler的父類,它提供了最基本的方法,例如default_open()、protocol_request()等。
- HTTPDefaultErrorHandler:用於處理HTTP響應錯誤,錯誤都會丟擲HTTPError型別的異常。
- HTTPRedirectHandler:用於處理重定向。
- HTTPCookieProcessor:用於處理Cookies。
- ProxyHandler:用於設定代理,預設代理為空。
- HTTPPasswordMgr:用於管理密碼,它維護了使用者名稱和密碼的表。
- HTTPBasicAuthHandler:用於管理認證,如果一個連結開啟時需要認證,那麼可以用它來解決認證問題。
另一個比較重要的類就是OpenerDirector,我們可以稱為Opener。urlopen()這個方法,實際上是urllib為我們提供的一個Opener。