1. 程式人生 > >【Python3 爬蟲學習筆記】基本庫的使用 1

【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。