- Python數(shù)據(jù)分析從入門到精通
- 李梓萌編著
- 1969字
- 2020-09-18 18:05:46
2.2 處理HTTP數(shù)據(jù)

HTTP是HyperText Transfer Protocol的縮寫,含義是超文本傳輸協(xié)議。HTTP是互聯(lián)網(wǎng)上應用最為廣泛的一種網(wǎng)絡協(xié)議,所有的WWW文件都必須遵守這個標準。在本節(jié)的內(nèi)容中,將詳細講解常用處理HTTP數(shù)據(jù)的知識。
2.2.1 使用內(nèi)置的http包處理數(shù)據(jù)
在Python語言中,使用內(nèi)置包http實現(xiàn)對HTTP協(xié)議的封裝。在包http中主要包含如下所示的模塊。
● http.client:底層的HTTP協(xié)議客戶端,可以為urllib.request模塊所用。
● http.server:提供處理socketserver模塊的功能類。
● http.cookies:提供在HTTP傳輸過程中處理Cookies應用的功能類。
● http.cookiejar:提供實現(xiàn)Cookies持久化支持的功能類。
在http.client模塊中,主要包括如下兩個處理客戶端應用的類。
● HTTPConnection:基于HTTP協(xié)議的訪問客戶端。
● HTTPResponse:基于HTTP協(xié)議的服務端回應。
在下面的實例文件fang.py中,演示了使用http.client.HTTPConnection對象訪問指定網(wǎng)站的過程。
源碼路徑:daima\2\2-2\fang.py

在上述實例代碼中只實現(xiàn)了一個基本的訪問實例,首先,實例化http.client.HTTPConnection設置請求的方法為GET,然后,使用getresponse()方法獲取訪問的網(wǎng)頁,并打印輸出響應的狀態(tài)。執(zhí)行效果如圖2-2所示。
在現(xiàn)實應用中,有時需要通過HTTP協(xié)議以客戶端的形式訪問多種服務,例如下載服務器中的數(shù)據(jù),或與一個基于REST的API進行交互。通過使用urllib.request模塊,可以實現(xiàn)簡單的客戶端訪問任務,例如要發(fā)送一個簡單的HTTP GET請求到遠端服務器上,只需通過下面的實例文件fang1.py即可實現(xiàn)。

圖2-2 執(zhí)行效果
源碼路徑:daima\2\2-2\fang1.py

執(zhí)行后會輸出:


2.2.2 使用庫requests處理數(shù)據(jù)
庫Requests是用Python語言基于urllib編寫的,采用的是Apache2 Licensed開源協(xié)議的HTTP庫,Requests會比urllib更加方便,可以節(jié)約開發(fā)者大量的時間。
可以使用如下兩種命令安裝庫requests。

在下面的實例文件Requests01.py中,演示了使用庫requests返回指定URL地址請求的過程。
源碼路徑:daima\2\2-2\Requests01.py

在上述代碼中,創(chuàng)建了一個名為r的response對象,可以從這個對象中獲取所有想要的信息。執(zhí)行后會輸出:

上述實例只演示get接口的用法,其他接口的用法也十分簡單:


例如查詢http://httpbin.org/get頁面的具體參數(shù),需要在url里面加上這個參數(shù)。假如查看有沒有Host=httpbin.org這條數(shù)據(jù),url形式應該是http://httpbin.org/get?Host=httpbin.org。在下面的實例文件Requests02.py中,提交的數(shù)據(jù)是往這個地址傳送data里的數(shù)據(jù)。
源碼路徑:daima\2\2-2\Requests02.py

執(zhí)行后會輸出:

2.2.3 使用庫httplib2處理數(shù)據(jù)
在Python程序中,經(jīng)常使用第三方的開源庫httplib2來處理HTTP數(shù)據(jù)。在使用庫httplib2之前,需要使用如下兩種命令安裝庫httplib2:

(1)獲取內(nèi)容
一旦擁有Http對象,能非常簡單地獲取網(wǎng)頁數(shù)據(jù),只需將要獲取的數(shù)據(jù)的地址作為參數(shù)調(diào)用request()方法即可,這會對該url執(zhí)行一個http GET請求。例如在下面的實例文件http201.py中,演示了使用庫httplib2獲取網(wǎng)頁數(shù)據(jù)的過程。
源碼路徑:daima\2\2-2\http201.py

通過上述代碼,方法request()會返回如下所示的兩個值。
● 第一個:一個httplib2.Response對象,包含服務器返回的所有http頭,如status為200則表示請求成功。
● 第二個:包含了HTTP服務器返回的實際數(shù)據(jù)的變量content。不是字符串的返回格式,而是以bytes對象數(shù)據(jù)的形式返回。如果需要返回一個字符串,需要確定字符編碼,并自定義實現(xiàn)字符轉(zhuǎn)換。
(2)處理緩存
與Python內(nèi)置庫http.client相比,庫httplib2的最大優(yōu)勢是可以處理緩存數(shù)據(jù)。例如在下面的實例文件http202.py中,演示了使用庫httplib2處理網(wǎng)頁緩存數(shù)據(jù)的過程。
源碼路徑:daima\2\2-2\http202.py

執(zhí)行后輸出網(wǎng)頁的源碼,并獲取帶有緩存的HTTP對象h1,被存儲在當前環(huán)境的“.cache"目錄下。


在上述輸出效果的最后一行中,顯示debug值為True,說明是從本地的cache緩存進行讀取的,沒經(jīng)過原網(wǎng)站運行解析,提高了輸出速度。但如果不想讀取緩存數(shù)據(jù),則只需通過如下代碼即可實現(xiàn)。

在使用庫httplib2時,可以在發(fā)出的請求中添加任意的HTTP頭部。為了跳過所有緩存,包括本地的磁盤緩存和遠程服務器之間的緩存代理,只需在headers字典中加入上面的no-cache頭即可。
(3)處理Last-Modified和ETag頭
在HTTP協(xié)議中,定義了如下兩個重要的屬性。
● Last-Modified:標記此文件在服務器端的最后修改時間。
● Etag:用于標識URL對象是否改變。
根據(jù)上述兩個屬性,如果發(fā)現(xiàn)本地緩存已不是最新的,客戶端可以在發(fā)送下一個請求時發(fā)送驗證器來檢查數(shù)據(jù)是否發(fā)生改變。如果數(shù)據(jù)沒有改變,服務器會返回304狀態(tài)碼,但不返回數(shù)據(jù)。
(4)POST發(fā)送構(gòu)造數(shù)據(jù)
在下面的實例文件http203.py中,演示了使用POST發(fā)送構(gòu)造數(shù)據(jù)的過程。
源碼路徑:daima\2\2-2\http203.py

執(zhí)行后會輸出:

在上述代碼中,add_credentials()方法的第三個參數(shù)identi.ca表示該證書的有效域名。建議讀者一定要設置這個參數(shù),如果省略了這個參數(shù),當再次用httplib2.Http對象訪問另一個需要認證的站點時,可能會導致httplib2將一個站點的用戶名密碼泄漏給其他站點,這樣就會造成安全問題。
另外,因為httplib2返回的是字節(jié)串(bytes)數(shù)據(jù),而不是字符串。所以為了將返回數(shù)據(jù)轉(zhuǎn)化為字符串格式,需要用合適的字符編碼進行解碼。例如:

2.2.4 使用庫urllib3處理數(shù)據(jù)
在Python應用中,庫urllib3提供了一個線程安全的連接池,能夠以post方式傳輸文件。可以使用如下兩種命令安裝庫urllib3。

在下面的實例文件urllib303.py中,演示了使用庫urllib3中的post()方法創(chuàng)建請求的過程。
源碼路徑:daima\2\2-2\urllib303.py

執(zhí)行后會輸出:


在下面的實例文件urllib305.py中,演示了使用庫urllib3獲取遠程CSV數(shù)據(jù)的過程。
源碼路徑:daima\2\2-2\urllib305.py


執(zhí)行后會將這兩個遠程CSV文件下載保存到本地,如圖2-3所示。

圖2-3 下載保存到本地的CSV文件
在下面的實例文件urllib302.py中,演示了使用庫urllib3抓取顯示鳳凰網(wǎng)頭條新聞的方法。
源碼路徑:daima\2\2-2\urllib302.py


由于頭條新聞是隨著時間的推移發(fā)生變化的,所以每次的執(zhí)行效果可能不一樣。