目錄
一、網絡爬蟲的介紹
1.網絡爬蟲庫
2.robots.txt 規則
二、requests 庫和網頁源代碼
1.requests 庫的安裝
2.網頁源代碼
三、獲取網頁資源
1.get () 函數
(1)get() 搜索信息
(2)get() 添加信息
2.返回 Response 對象
(1)Response 的屬性
(2)設置編碼
(3)返回網頁內容
一、網絡爬蟲的介紹
1.網絡爬蟲庫
網絡爬蟲通俗來講就是使用代碼將 HTML 網頁的內容下載到本地的過程。爬取網頁主要是為了獲取網頁中的關鍵信息,例如網頁中的數據、圖片、視頻等。Python 語言中提供了多個具有爬蟲功能的庫,下面將具體介紹。
urllib 庫:是 Python 自帶的標準庫,無須下載、安裝即可直接使用。urllib 庫中包含大量的爬蟲功能,但其代碼編寫略微復雜。
requests 庫:是 Python 的第三方庫,需要下載、安裝之后才能使用。由于 requests 庫是在 urllib 庫的基礎上建立的,它包含 urllib 庫的功能,這使得 requests 庫中的函數和方法的使用更加友好,因此 requests 庫使用起來更加簡潔、方便。
scrapy 庫:是 Python 的第三方庫,需要下載、安裝之后才能使用。scrapy 庫是一個適用于專業應用程序開發的網絡爬蟲庫。scrapy 庫集合了爬蟲的框架,通過框架可創建一個專業爬蟲系統。
selenium 庫:是 Python 的第三方庫,需要下載、安裝后才能使用。selenium 庫可用于驅動計算機中的瀏覽器執行相關命令,而無須用戶手動操作。常用于自動驅動瀏覽器實現辦公自動化和 Web 應用程序測試。
本章主要介紹 requests 庫和 selenium 庫。
2.robots.txt 規則
在正式學習網絡爬蟲之前,需要掌握爬取規則,不是網站中的所有信息都允許被爬取,也不是所有的網站都允許被爬取。在大部分網站的根目錄中存在一個 robots.txt 文件,該文件用于聲明此網站中禁止訪問的 url 和可以訪問的 url。用戶只需在網站域名后面加上 /robots.txt 即可讀取此文件的內容。
例如要獲取豆瓣官網中的 robots.txt 文件,打開瀏覽器輸入豆瓣官網域名并在域名后加上 /robots.txt,按 Enter 鍵即可,如圖所示。豆瓣官網的主域名下存在大量的子域名,例如某個電影的影評 url 是在主域名的基礎上增加子目錄,其形式與磁盤中的目錄路徑相同。
robots.txt 規則用于表明當前網站中的哪些內容是可以訪問的,哪些內容是禁止訪問的。接下來具體介紹 robots.txt 文件的內容。
User-agent:表示訪問網站的搜索引擎,如圖中一共存在 3 個 User-agent 內容,第 1 個 User-agent 的值為 *,表示所有類型的搜索引擎都需要遵守第 2~21 行的規則。第 2 個 User-agent 的值為 Wandoujia Spider,表示 Wandoujia Spider 搜索引擎需要遵守的規則。第 3 個 User-agent 的值為 Mediapartners-Google,表示Mediapartners-Google 搜索引擎需要遵守的規則。
Disallow:表明該搜索引擎不允許訪問的 url。例如圖中的 /subject_search,表明豆瓣官網根目錄下的 /subject_search 是不允許被訪問的,讀者可以嘗試使用瀏覽器訪問此 url 并觀察結果。當 Disallow 的值為 / 時,表明不允許此搜索引擎訪問網站的任何內容。例如圖所示的 Wandoujia Spider 搜索引擎就不能訪問豆瓣官網中的任何信息。
Allow:表明允許該搜索引擎訪問的 url。例如圖中的 /ads.txt 是允許被任何搜索引擎訪問的。
Sitemap:網站地圖,用于提供網站中所有可以被爬取的 url,方便搜索引擎能夠快速爬取到對應網頁。
#:表明注釋,與 Python 中的注釋概念相同。Crawl - delay:5 用于提醒用戶在使用爬蟲工具時,每次訪問之間需要延遲 5 秒鐘,這是為了避免因用戶頻繁訪問而導致服務器擁擠,使得用戶無法正常使用瀏覽器。每個網站在同一時間內有訪問上限,超過上限將導致新用戶無法訪問,例如在 “雙十一” 期間會有大量用戶訪問同一個購物網站,這時候如果使用爬蟲工具頻繁訪問該網站,且爬蟲工具是由代碼實現的,訪問速度將會非常快,就可能導致網站擁堵,使用戶無法正常進入網站,還可能造成商家的經濟損失。
因此讀者在使用爬蟲工具訪問某網站時,需要先閱讀網站的 robots.txt 規則并嚴格遵守此規則。但有些網站并沒有設定 robots.txt 規則,例如訪問人民郵電出版社官網的 robots.txt 規則的結果如圖所示。當網站中沒有 robots.txt 規則時,一般默認允許用戶使用爬蟲工具訪問,但仍然要遵守《中華人民共和國網絡安全法》等。
二、requests 庫和網頁源代碼
1.requests 庫的安裝
在命令提示符窗口或終端中執行以下命令:
pip install requests
2.網頁源代碼
用戶在使用瀏覽器訪問網頁時,往往會忽視網頁的源代碼,而獲取網頁中的信息需要從網頁的源代碼出發。
例如使用Edge瀏覽器打開人民郵電出版社官網中的期刊頁。在網頁空白處單擊鼠標右鍵,選擇快捷菜單中的 “查看頁面源代碼” 即可打開當前網頁的源代碼信息頁面,如圖所示。
網頁中的源代碼形式與?HTML 代碼形式基本相同,讀者可嘗試閱讀網頁中的源代碼。通過源代碼可以輕松地獲取網頁中的文字、圖片、視頻等信息,還可以獲取圖片或視頻文件的 url 并將文件下載到本地。
而一個網頁除了 HTML 代碼還包含 JavaScript 腳本語言代碼,JavaScript 腳本語言代碼使得瀏覽器可以解析和渲染網頁源代碼,使得用戶可以瀏覽到圖形化界面,而不是閱讀純文本代碼。網頁中有大量數據是包含在 JavaScript 腳本語言代碼中的,而通過查看源代碼的方式是無法獲取這些數據的。例如圖中的圖片信息在網頁源代碼中是無法找到的,但可以通過檢查(在網頁空白處單擊鼠標右鍵,選擇快捷菜單中的 “檢查” 選項)窗口查看渲染后的網頁內容,找到對應圖片的 url,如圖所示。
獲取人民郵電出版社官網中期刊頁的《通信學報》封面圖片 url 的步驟如下。
步驟 1,單擊檢查窗口中的元素選擇按鈕,如圖 15 - 6 所示的標注框所在位置內的圖標。
步驟 2,單擊網頁中的圖片位置,檢查窗口將會自動跳轉到該圖片對應的源代碼位置。
步驟 3,淺藍色部分的<img src="/upload/2017/06/53def7a9b43044a1b1afd1991d82a323.png">
為圖片的源代碼內容,其中upload/2017/06/53def7a9b43044a1b1afd1991d82a323.png
為圖片在網站服務器中的目錄地址,完整的 url 只需要在前面加入網站主域名即可。
雖然網站中的內容是動態更新的,但只需按照上面介紹的方法執行即可獲取大部分網站中的信息,包括文字、圖片、音樂、視頻等。
三、獲取網頁資源
requests 庫具有獲取網頁內容和向網頁中提交信息的功能。
1.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
方法用于獲取相應的文本內容,即網頁的源代碼。
運行結果:
執行代碼后的輸出結果如圖所示。對比使用代碼輸出的信息和使用瀏覽器訪問的網頁源代碼,它們的內容是相同的。
(1)get() 搜索信息
當在網頁中搜索是人民郵電出版社中的某些指定信息時,可以在圖所示的搜索框中輸入搜索信息,例如輸入關鍵詞"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” 的信息。
(2)get() 添加信息
get() 函數中第 2 個參數 params 會以字典的形式在 url 后自動添加信息,需要提前將 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=excel
,該使用形式便于靈活設定需要搜索的信息,即可以添加或刪除字典信息。
第 4 行代碼輸出返回的 Response 對象中的 url,即獲取網頁的 url。
2.返回 Response 對象
通過 get () 函數獲取 HTML 網頁內容后,由于網頁的多樣性,通常還需要對網頁返回的 Response 對象進行設置。本小節將主要講解類 Response 中的方法。
(1)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 r.status_code == 200:print(r.text)
else:print('本次訪問失敗')
第 3 行代碼輸出 Response 對象返回的狀態碼。第 4 行代碼用于判斷狀態碼是否為 200,如果為 200,則輸出獲取的網頁內容,否則表明訪問存在異常。?
headers(響應頭):服務器返回的附加信息,主要包括服務器傳遞的數據類型、使用的壓縮方法、語言、服務器的信息、響應該請求的時間等。
url:響應的最終 url 位置。
encoding:訪問 r.text 時使用的編碼。
cookies:服務器返回的文件。這是服務器為辨別用戶身份,對用戶操作進行會話跟蹤而存儲在用戶本地終端上的數據。
(2)設置編碼
當訪問一個網頁時,如果獲取的內容是亂碼。這是由網頁讀取編碼錯誤導致的,可以通過設置requests.get(url)
返回的 Response 對象的encoding='utf - 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 行代碼設置自動識別網頁的編碼方式,執行代碼后的輸出結果中將包含可識別的文字,而不再是亂碼。當設置自動識別編碼方式后依然出現內容亂碼時,讀者需要自行設置encoding
編碼方式。
(3)返回網頁內容
Response 對象中返回網頁內容有兩種方法,分別是 text() 方法和 content() 方法,其中 text() 方法在前面的內容中有介紹,它是以字符串的形式返回網頁內容。而 content() 方法是以二進制的形式返回網頁內容,常用于直接保存網頁中的媒體文件。
示例代碼(下載人民郵電出版社官網中的圖片):
import requests
r = requests.get('https://cdn.ptpress.cn/uploadimg/Material/978-7-115-41359-8/72jpg/41359.jpg')
f2 = open('b.jpg','wb')
f2.write(r.content)
f2.close()
第 2 行代碼使用 get() 方法訪問了圖片 url。?
第 3 行代碼使用 open() 函數創建了一個b.jpg
文件,并且設置以二進制寫入的模式。
第 4 行代碼將獲取的 url 內容以二進制形式寫入文件。
執行代碼后將在相應文件夾中存儲一張圖片,如圖所示。
運行結果: