網絡爬蟲庫
網絡爬蟲通俗來講就是使用代碼將HTML網頁的內容下載到本地的過程。爬取網頁主要是為了獲取網中的關鍵信息,例如網頁中的數據、圖片、視頻等。Python語言中提供了多個具有爬蟲功能的庫,下面將具的介紹。
urlib庫:是Python自帶的標準庫,無須下載、安裝即可直接使用。urllib庫中包含大量的爬蟲功能,但其代碼編寫略微復雜。
requests庫:是python的第三方庫,需要下載、安裝之后才能使用。由于requests庫是在urllib庫的基礎上建立的,它包含urlib庫的功能,這使得requests庫中的函數和方法的使用更加友好,因此requests庫使用起來更加簡潔、方便。
scrapy庫:是Python的第三方庫,需要下載、安裝之后才能使用。scrapy庫是一個適用于專業應用程序開發的網絡爬蟲庫。scrapy庫集合了爬蟲的框架,通過框架可創建一個專業爬蟲系統。
selenium庫:是Python的第三方庫,需要下載、安裝后才能使用。selenium庫可用于驅動計算機中的瀏覽器執行相關命令,而無須用戶手動操作。常用于自動驅動瀏覽器實現辦公自動化和Web應用程序測試。
基于辦公自動化的使用場景,本章主要介紹requests庫和selenium庫。而scrapy庫是專業級爬蟲庫,如果讀者對網絡爬蟲感興趣,可以進入Python爬蟲領域進行更深層次的學習。
robots.txt規則
在正式學習網絡爬蟲之前,讀者需要掌握爬取規則,不是網站中的所有信息都允許被爬取,也不是所有的網站都允許被爬取。在大部分網站的根目錄中存在一個robots.txt文件,該文件用于聲明此網站中禁止訪問的url和可以訪問的url。用戶只需在網站域名后面加上/robots.txt即可讀取此文件的內容。
例如要獲取豆瓣官網中的robots.txt文件,打開瀏覽器輸入豆瓣官網域名并在域名后加上/robots.txt,按Enter鍵即可,如圖15-1所示。豆瓣官網的主域名下存在大量的子域名,例如某個電影的影評url是在主域名的基礎上增加子目錄,其形式與磁盤中的目錄路徑相同。
robots.txt規則用于表明當前網站中的哪些內容是可以訪問的哪些內容是禁止訪問的。接下來具體介紹robots.txt文件的內容。
User-agent:表示訪問網站的搜索引擎,第1個User-agent的值為*,表示所有類型的搜索引擎都需要遵守第2~21行的規則。第2個User-agent的值頭W彥andouiia Spider,表示Wandoujia Spider搜索引擎需要遵守的規則。
requests 庫和網頁源代碼
主要講解requests庫的安裝及如何獲取網頁源代碼。
requests 庫的安裝
在命令提示符窗口或終端中執行以下命令:
pip install requests
安裝成功后可使用以下命令查看庫的信息:
pip show requests
返回信息包含當前安裝的requests庫的版本信息、官方地址、安裝目錄等。
網頁源代碼
用戶在使用瀏覽器訪同網頁時,往往會忽視網頁的源代碼,而獲取網頁中的信息需要從網頁的源代碼出發。
例如使用瀏覽器(本書使用的是chrome瀏覽器)打開人民郵電出版社官網中的期刊頁。在網頁空白處單鼠標右鍵,選擇快捷菜單中的“查看頁面源代碼”即可打開當前網頁的源代碼信息頁面。
網頁中的源代碼形式與第14章的HTML代碼形式基本相同,讀者可嘗試閱讀網頁中的源代碼。通過源代碼可以輕松地獲取網頁中的文字、圖片、視頻等信息,還可以獲取圖片或視頻文件的url并將文件下載到本地。
而一個網頁除了HTML代碼還包含]avaScript腳本語言代碼,JavaScript腳本語言代碼使得瀏覽器可以解析和渲染網頁源代碼,使得用戶可以閱覽到圖形化界面,而不是閱讀純文本代碼。網頁中有大量數據是包含在JavaScript腳本語言代碼中的,而通過査看源代碼的方式是無法獲取這些數據的。例如圖15-4中的圖片信息在網頁源代碼中是無法找到的,但可以通過檢查窗口查看渲染后的網頁內容,找到對應圖片的url。
獲取人民郵電出版社官網中期刊頁的《通信學報》封面圖片url的步驟如下,步驟1,單擊檢查窗口中的元素選擇按鈕,如圖15-6所示的標注框所在位置內的圖標。步驟2,單擊網頁中的圖片位置,檢查窗口將會自動跳轉到該圖片對應的源代碼位置。
步驟3,淺藍色部分的<img upload/2017/06/53def7a9b43044a1b1afd1991d82a323.png>為圖片的源代碼內容,其中upload/2017/06/53def7a9b43044a1b1afd1991d82a323.png為圖片在網站服務器中的目錄地址,完整的ur1只需要在前面加入網站主域名即可。
獲取網頁資源
requests庫具有獲取網頁內容和向網頁中提交信息的功能,本節主要介紹如何獲取網頁內容及如何對獲取的網頁內容進行處理。
get()函數
在requests庫中獲取HTML網頁內容的方法是使用get()函數。其使用形式如下:
get (url, params=None, **kwargs)
參數url:表示需要獲取的HTML網址(也稱為url)。
參數params:表示可選參數,以字典的形式發送信息,當需要向網頁中提交查詢信息時使用。
參數**kwargs:表示請求采用的可選參數。
返回值:返回一個由類Response創建的對象。類Response位于requests庫的models.py文件中。
示例代碼:
import requests
r=requests.get('https://www.ptpress.com.cn/')
print(r.text)
第1行代碼導入了requests庫。
第2行使用requests庫中的get()函數獲取人民郵電出版社的官方網址,并返回一個Response對象給變量r。
第3行代碼使用print()語句輸出變量r的text方法,Response對象中的text方法用于獲取相應的文本內容即網頁的源代碼。
執行代碼后的輸出結果如圖15-7所示,“Squeezed text(1019line).”表示獲取的內容較多,IDLE會自動將內容收縮起來,可以用鼠標右鍵單擊此處并選擇“view”查看返回的完整信息,如圖15-8所示。對比使用代碼輸出的信息和使用瀏覽器訪問的網頁源代碼,它們的內容是相同的。
get()搜索信息
當在網頁中搜索人民郵電出版社中的某些指定信息時,可以在圖15-9所示的搜索框中輸入搜索信息,例輸入關鍵詞“Excel”。
從搜索結果網頁中可以看到當前頁面的網址為https://www.ptpress.com.cn/search?keyword=excel其中https://www.ptpress.com.cn/為官網主頁,search表示搜索,keyword表示搜索的關鍵詞(這里值為
excel,表示需要搜索的關鍵詞為“excel”),“?”用于分隔search和keyword。
在其他網頁中搜索也有與以上類似的效果,search或keyword可能會用其他字符表示,但基本形式是相同的。讀者可在其他網頁中進行嘗試,例如使用百度的網址+s?wd=excel可以搜索到關鍵詞為“excel”的內容其中s為search的縮寫,wd為word的縮寫。
在requests庫中可以充分利用以上方法實現獲取網頁中的資源。
示例代碼:
import requests
r=requests.get('https://www.ptpress.com.cn/search?keyword=word')
print(r.text)
第2行代碼用于實現在人民郵電出版社官網中搜索關鍵詞為“word”的信息
get()添加信息
get()函數中第2個參數params會以字典的形式在ur1后自動添加信息,需要提前將params定義為字典示例代碼:
import requests
info ={'keyword':'Excel'}
r=requests.get('https://www.ptpress.com.cn/search',params=info)
print(r.url)
print(r.text)
第2行代碼建立字典info,包含一個鍵值對。
第3行代碼使用get()函數獲取網頁,由于get()中包含參數params,因此系統會自動在url后添加字典信息形式為https://www.ptpress.com.cn/search?keyword=exce1,該使用形式便于靈活設定需要搜索的信息即可以添加或刪除字典信息。
第4行代碼輸出返回的Response對象中的url,即獲取網頁的url。
返回 Response 對象
通過get()函數獲取HTML網頁內容后,由于網頁的多樣性,通常還需要對網頁返回的Response對象進行設置。本小節將主要講解類Response中的方法。
Response 的屬性
Response包含的屬性有status_code、headers、url、encoding、cookies等。
status_code(狀態碼):當獲取一個HTML網頁時,網頁所在的服務器會返回一個狀態碼,表明本次獲取網頁的狀態。例如訪問人民郵電出版社官網,當使用get()函數發出請求時,人民郵電出版社官網的服務器接收到請求信息后,會先判斷請求信息是否合理,如果請求合理則返回狀態碼200和網頁信息;如果請求不合理則返回一個異常狀態碼。
常見的HTTP(Hypertext Transfer Protocol,超文本傳送協議)狀態碼有200(請求成功)、301(網頁內容被永久轉移到其他url)、404(請求的網頁不存在)、500(內部服務器錯誤)等,更多狀態碼可以使用搜索引擎查詢。
因此在使用get()函數請求訪問網頁時,為了確保獲取正確的網頁信息,需要判斷服務器返回的狀態碼是否為200。Response對象中的status_code為服務器返回的狀態碼。
示例代碼:
import requests
r=requests.get('https://www.ptpress.com.cn')
print(r.status_code)
if rstatus_code == 200:
????????print(r.text)
else:
????????print('本次訪問失敗')
第3行代碼輸出Response對象返回的狀態碼。第4行代碼用于判斷狀態碼是否為200,如果為200,則輸出獲取的網頁內容,否則表明訪問存在異常。
header(響應頭):服務器返回的附加信息,主要包括服務器傳遞的數據類型、使用的壓縮方法、語言、服務器的信息、響應該請求的時間等。
url:響應的最終url位置。
encoding:訪問r.text時使用的編碼。
設置編碼
當訪間一個網頁時,如果獲取的內容是亂碼,例如圖15-12所示的內容為訪間百度官網后返回的信息,其中存在大量的亂碼信息。這是由網頁讀取編碼錯誤導致的,可以通過設置requests.get(url)返回的Bespons對象的encoding='utr-8"來修改“Response對象.text”文本內容的編碼方式。同時Response對象中提供了apparent_encoding()方法來自動識別網頁的編碼方式,不過由于此方法是由機器自動識別,因此可能會存在識別錯誤的情況(大部分情況下是可用的)。
如果要設置自動識別網頁的編碼方式,可以使用以下形式:
Response對象.encoding=Response對象,apparent_encoding
import requests
r=requests.get('此處填入'百度官網地址'.com')
r.encoding =r.apparent encoding
print(r.text)
第3行代碼設置自動識別網頁的編碼方式,執行代碼后的輸出結果中將包含可識別的文字,而不再是亂碼,如圖15-13所示。當設置自動識別編碼方式后依然出現內容亂碼時,讀者需要自行設置encoding編碼方式。
返回網頁內容
Response對象中返回網頁內容有兩種方法,分別是te緇爍氮xt総()方法和content()方法,其中text()方法在前面的內容中有介紹,它是以字符串的形式返回網頁內容。而content()方法是以二進制的形式返回網頁內容,常用于直接保存網頁中的媒體文件。
示例代碼(下載人民郵電出版社官網中的圖片):
import requests
r=requestsget('https://cdn.ptpress.cn/uploadimg/Materia1/978-7-115-41359-8/72jpg/4135jpg')
f2 = open('b.jpg','wb')
f2.write(r.content)
f2.close()
第2行代碼使用get()方法訪問了圖片url。
第3行代碼使用open()函數創建了一個bjpg文件,并且設置以二進制寫入的模式
第4行代碼將獲取的url內容以二進制形式寫入文件。
執行代碼后將在相應文件夾中存儲一張圖片.
提交信息到網頁
requests庫除了可以從網頁中獲取資源,還可以將信息提交到網頁中,本節將主要介紹如何使用實現將信息上傳到網站服務器中。
瀏覽器提交請求
在15.3節中介紹了如何通過requests庫獲取網頁的內容,而當需要向網頁中提交信息時,可以requests庫中的post()函數來實現,提交內容包含表單、圖片、文件等類型的數據。
可以在瀏覽器的檢查窗口中觀察到數據提交的過程。以在人郵教育社區中修改用戶密碼為例,觀察瀏覽器提交數據的步驟如下。
步驟1,登錄用戶賬戶后,進入修改密碼界面,如圖15-18所示。需要在指定位置輸入當前密碼和新密碼,這種文本框中的數據稱為表單信息。
步驟2,在網頁空白處單擊鼠標右鍵并進入檢查窗口,單擊“Network”進入Network窗口,接下來在網頁中輸入用戶的當前密碼、新密碼、確認密碼,并單擊“修改密碼”按鈕,如圖15-19所示。
步驟3,提交信息后,在右邊的Network窗口中將不斷獲取網頁交互的信息。
為驟4,找到提交密碼的交互信息。在Name窗口中單擊"change-password”,觀察其"Hearders”選
不的售息、可以發現在:G2neral”區城中的RequestManna(更示情2d”、碼務法)(為POST,書信息是通過P09請求來提交數據的,如圖15-21所示。而在最0(的示請來網D3萬花設單數據)區城中了剛剛輸入的密碼,其中OldPassword對應網頁中的當前密碼。的“pa.Dza對應網頁中的新密碼。8frmPaswOHd對應網頁中的確認密碼,它們的值正好為用戶限剛輸入P&8”0n1522所示。由此可以CmName窗口中的change-password是提交給服務器的信息。
以上內容是使用瀏覽器實現通過p0St請求提交數據的過程,接下來介紹使用requests庫模擬瀏覽器提交調。,實現通過post請求將表單中的數據提交給服務器。
post()函數
post()函數可用于向網站發送數據請求。其使用形式如下:
bost (url,data=None, json=None, **kwargs)
參數url:表示網站url。
參數data:表示需要發送的數據對象,可以為字典、元組、列表、字節數據或文件。
參數json:表示需要發送的數據對象,該數據對象為JSON數據(具體內容見17.3節)。
參數**kwargs:表示請求采用的可選參數。
返回值:使用post()函數后返回一個Response對象。
示例代碼:
import requests
d=('0ldpassword':'123456python','Newpassword':'123python','conflrmpassword' :'123python' }
r=requests.post('https://account.ryjiaoyu.com/change-password', data-d)
print(z.text)
第2行代碼使用字典的形式保存了需要上傳的數據。
第3行代碼使用post()函數訪問修改密碼網頁ur,并提交修改密碼數據。
執行此代碼后本質上還無法完成使用代碼修改密碼,因為在修改密碼前還需要登錄賬戶,這里代碼并沒有實現賬戶的登錄,此處僅展示上傳表單數據的方法。