3.爬取數(shù)據(jù)-urllib庫
怎樣扒網(wǎng)頁呢?
其實就是根據(jù)URL來獲取它的網(wǎng)頁信息,雖然我們在瀏覽器中看到的是一幅幅優(yōu)美的畫面,但是其實是由瀏覽器解釋才呈現(xiàn)出來的,實質(zhì)它是一段HTML代碼,加 JS、CSS,如果把網(wǎng)頁比作一個人,那么HTML便是他的骨架,JS便是他的肌肉,CSS便是它的衣服。所以最重要的部分是存在于HTML中的,下面我們就寫個例子來扒一個網(wǎng)頁下來
from urllib.request import urlopen
response = urlopen("http://www.baidu.com")
print(response.read().decode())
真正的程序就兩行,執(zhí)行如下命令查看運行結(jié)果,感受一下
看,這個網(wǎng)頁的源碼已經(jīng)被我們扒下來了,是不是很酸爽?
2. 常見到的方法
requset.urlopen(url,data,timeout)
第一個參數(shù)url即為URL,第二個參數(shù)data是訪問URL時要傳送的數(shù)據(jù),第三個timeout是設(shè)置超時時間。
第二三個參數(shù)是可以不傳送的,data默認(rèn)為空None,timeout默認(rèn)為 socket._GLOBAL_DEFAULT_TIMEOUT
第一個參數(shù)URL是必須要傳送的,在這個例子里面我們傳送了百度的URL,執(zhí)行urlopen方法之后,返回一個response對象,返回信息便保存在這里面。
response.read()
read()方法就是讀取文件里的全部內(nèi)容,返回bytes類型
response.getcode()
返回 HTTP的響應(yīng)碼,成功返回200,4服務(wù)器頁面出錯,5服務(wù)器問題
response.geturl()
返回 返回實際數(shù)據(jù)的實際URL,防止重定向問題
response.info()
返回 服務(wù)器響應(yīng)的HTTP報頭
3. Request對象
其實上面的urlopen參數(shù)可以傳入一個request請求,它其實就是一個Request類的實例,構(gòu)造時需要傳入Url,Data等等的內(nèi)容。比如上面的兩行代碼,我們可以這么改寫
from urllib.request import urlopen
from urllib.request import Request
request = Request("http://www.baidu.com")
response = urlopen(requst)
print response.read().decode()
運行結(jié)果是完全一樣的,只不過中間多了一個request對象,推薦大家這么寫,因為在構(gòu)建請求時還需要加入好多內(nèi)容,通過構(gòu)建一個request,服務(wù)器響應(yīng)請求得到應(yīng)答,這樣顯得邏輯上清晰明確
4. Get 請求
大部分被傳輸?shù)綖g覽器的html,images,js,css, … 都是通過GET方法發(fā)出請求的。它是獲取數(shù)據(jù)的主要方法
例如:www.baidu.com 搜索
Get請求的參數(shù)都是在Url中體現(xiàn)的,如果有中文,需要轉(zhuǎn)碼,這時我們可使用
urllib.parse.urlencode()
urllib.parse. quote()
5. Post 請求
我們說了Request請求對象的里有data參數(shù),它就是用在POST里的,我們要傳送的數(shù)據(jù)就是這個參數(shù)data,data是一個字典,里面要匹配鍵值對
發(fā)送請求/響應(yīng)header頭的含義:
名稱含義Accept告訴服務(wù)器,客戶端支持的數(shù)據(jù)類型Accept-Charset告訴服務(wù)器,客戶端采用的編碼Accept-Encoding告訴服務(wù)器,客戶機支持的數(shù)據(jù)壓縮格式Accept-Language告訴服務(wù)器,客戶機的語言環(huán)境Host客戶機通過這個頭告訴服務(wù)器,想訪問的主機名If-Modified-Since客戶機通過這個頭告訴服務(wù)器,資源的緩存時間Referer客戶機通過這個頭告訴服務(wù)器,它是從哪個資源來訪問服務(wù)器的。(一般用于防盜鏈)User-Agent客戶機通過這個頭告訴服務(wù)器,客戶機的軟件環(huán)境Cookie客戶機通過這個頭告訴服務(wù)器,可以向服務(wù)器帶數(shù)據(jù)Refresh服務(wù)器通過這個頭,告訴瀏覽器隔多長時間刷新一次Content-Type服務(wù)器通過這個頭,回送數(shù)據(jù)的類型Content-Language服務(wù)器通過這個頭,告訴服務(wù)器的語言環(huán)境Server服務(wù)器通過這個頭,告訴瀏覽器服務(wù)器的類型Content-Encoding服務(wù)器通過這個頭,告訴瀏覽器數(shù)據(jù)采用的壓縮格式Content-Length服務(wù)器通過這個頭,告訴瀏覽器回送數(shù)據(jù)的長度
6. 響應(yīng)的編碼
響應(yīng)狀態(tài)碼
響應(yīng)狀態(tài)代碼有三位數(shù)字組成,第一個數(shù)字定義了響應(yīng)的類別,且有五種可能取值。 常見狀態(tài)碼:
號碼含義
100~199表示服務(wù)器成功接收部分請求,要求客戶端繼續(xù)提交其余請求才能完成整個處理過程200~299表示服務(wù)器成功接收請求并已完成整個處理過程。常用200(OK 請求成功)300~399為完成請求,客戶需進(jìn)一步細(xì)化請求。例如:請求的資源已經(jīng)移動一個新地址、常用302(所請求的頁面已經(jīng)臨時轉(zhuǎn)移至新的url)、307和304(使用緩存資源)400~499客戶端的請求有錯誤,常用404(服務(wù)器無法找到被請求的頁面)、403(服務(wù)器拒絕訪問,權(quán)限不夠)500~599服務(wù)器端出現(xiàn)錯誤,常用500(請求未完成。服務(wù)器遇到不可預(yù)知的情況)
7. Ajax的請求獲取數(shù)據(jù)
有些網(wǎng)頁內(nèi)容使用AJAX加載,而AJAX一般返回的是JSON,直接對AJAX地址進(jìn)行post或get,就返回JSON數(shù)據(jù)了
8. 請求 SSL證書驗證
https://www.baidu.com/
如果SSL證書驗證不通過,或者操作系統(tǒng)不信任服務(wù)器的安全證書,比如瀏覽器在訪問12306網(wǎng)站如:https://www.12306.cn/mormhweb/的時候,會警告用戶證書不受信任。(據(jù)說 12306 網(wǎng)站證書是自己做的,沒有通過CA認(rèn)證)
# 忽略SSL安全認(rèn)證
context = ssl._create_unverified_context()
# 添加到context參數(shù)里
response = urllib.request.urlopen(request, context = context)