上一篇文章講了爬蟲的工作原理,這篇文章以后就要重點開始講編程序了。
簡單爬蟲的的兩個步驟:
- 使用HTTPRequest工具模擬HTTP請求,接收到返回的文本。用于請求的包有: requests、urllib等。
- ?對接收的文本進行篩選,獲取想要的內容。用戶篩選文本的包有: bs4、lxml等。
爬蟲的第一步就是向網站發送HTTP請求,本篇文章的主要內容就是用python向網站發送請求,獲得網站的響應。
urllib庫
在Python的網絡編程世界中,urllib
庫是處理網絡請求的基礎庫之一。無論是獲取網頁內容、下載文件還是發送POST請求,urllib
都能提供強大的支持。
1. urllib庫簡介
urllib
是Python標準庫中的一個模塊,用于處理網絡請求。它包含多個子模塊,如urllib.request
、urllib.error
、urllib.parse
等,每個子模塊都有其特定的功能和用途。下面我們將逐一介紹這些子模塊的使用方法。
2. urllib.request模塊
urllib.request
模塊用于打開和讀取URLs。它提供了各種網絡請求的類和函數,如urlopen()
、Request()
等。
使用urlopen()
發送GET請求
某度搜索頁源代碼部分展示:
運行結果展示:
使用Request()
發送帶有請求頭的GET請求
什么是請求頭?
請求頭(Request Headers)?是HTTP請求的一部分,它包含了關于一個HTTP請求的屬性信息。這些屬性信息定義了請求的客戶端環境、請求的意圖以及請求的原始服務器應使用的其他屬性。一個HTTP請求通常由請求行、請求頭和請求體三部分組成,其中請求頭包含了多個屬性,每個屬性包含一個名字和一個值,兩者用冒號:
分隔。
在某瓣電影官網按下F12
進入開發者模式,點擊網絡,然后點擊文檔查看我們要爬取頁面的接口,我們選擇第一個,查看它的請求頭。如下圖:
這里做個解釋:左邊的一列其實就是網址的縮寫,我們很明顯可以看出來第一個就是我們輸入的網址,也就是我們要發送HTTP請求的網址,右邊就是它的請求頭信息。
各種請求頭信息:
- User-Agent:告訴服務器關于客戶端的環境信息,如瀏覽器類型、版本、操作系統、渲染引擎等。這有助于服務器返回與客戶端兼容的內容。(經常放到程序中,一般使用的時候隨便去網頁里復制一個就行)
- Accept:
Accept
?請求頭告訴服務器客戶端能夠處理哪些類型的響應內容,如text/html
、application/json
、image/jpeg
等。服務器將使用此信息來確定返回哪種類型的響應內容。 - Accept-Encoding:
Accept-Encoding
?請求頭列出了客戶端支持的壓縮編碼類型,如gzip
、deflate
等。服務器可以使用這些編碼來壓縮響應,以減少傳輸的數據量。 -
Accept-Language:
Accept-Language
?請求頭告訴服務器客戶端首選的語言,以便服務器能夠返回用該語言編寫的響應內容。這有助于實現內容的國際化和本地化。 -
Content-Type:
Content-Type
?請求頭(在POST或PUT請求中常見)描述了請求體的媒體類型。這告訴服務器請求體的內容格式,以便服務器能夠正確地解析數據。例如,對于JSON數據,Content-Type可能設置為application/json
。 -
Content-Length:
Content-Length
?請求頭告訴服務器請求體的長度(以字節為單位)。這對于需要知道請求體大小的服務器來說很有用。 -
Authorization:
Authorization
?請求頭包含客戶端提供給服務器的身份驗證憑據,通常用于HTTP身份驗證。例如,在基于令牌的認證中,客戶端可能會將令牌作為此頭的一部分發送。 -
Host:
Host
?請求頭指定了請求的目標域名和端口號(如果端口號不是默認的80或443)。這允許服務器區分來自不同域名的請求,并在同一IP地址上托管多個網站。 -
Cache-Control:
Cache-Control
?請求頭包含了關于請求緩存的指令。這些指令告訴緩存(如瀏覽器緩存或代理服務器緩存)如何緩存響應內容,以及何時可以重新驗證緩存的內容。 -
Cookie:
Cookie
?請求頭包含了由服務器之前設置的HTTP cookie。這些cookie可以用于會話管理、用戶跟蹤等目的。
除了上述常見的請求頭之外,還有許多其他請求頭,如Referer
(指示請求的來源頁面)、Connection
(指定連接類型,如keep-alive
)等。這些請求頭根據具體的應用場景和需求而有所不同。
這部分不理解的話可以先跳過,知道請求頭是用來偽裝爬蟲程序的就行了,后面實戰遇到的時候會再給大家針對案例講解。
為什么要加請求頭?
-
身份認證:一些網站要求用戶進行身份認證才能訪問某些資源。請求頭可以包含認證信息,如用戶名和密碼(雖然在現代應用中,這種做法通常會被更安全的方法如OAuth或JWT替代)。
-
緩存控制:請求頭中的
Cache-Control
字段可以控制瀏覽器或其他客戶端如何緩存請求的資源。例如,它可以指示服務器不要緩存某個資源,或者指示客戶端在特定時間后重新驗證緩存的資源。 -
內容協商:請求頭中的
Accept
字段可以告訴服務器客戶端能夠處理哪些類型的響應內容。例如,客戶端可以指定它期望接收HTML、XML、JSON或圖片等類型的響應。 -
自定義請求:通過添加自定義的請求頭,客戶端可以向服務器傳遞額外的信息,以便服務器能夠生成更符合客戶端需求的響應。例如,一個API請求可能會包含一個表示API版本或客戶端ID的自定義請求頭。
-
跨域資源共享(CORS):在Web開發中,跨域資源共享(CORS)是一個安全特性,它允許網頁從與其來源不同的源加載資源。CORS請求會包含一個名為
Origin
的請求頭,該頭字段用于描述請求的發起源。 -
防止緩存:通過在請求頭中添加特定的字段(如
Pragma: no-cache
或Cache-Control: no-cache
),可以確保瀏覽器或其他客戶端不會從緩存中加載資源,而是從服務器獲取最新的資源。 -
追蹤和調試:請求頭還可以包含用于追蹤和調試的信息,如用戶代理(User-Agent)字段可以告訴服務器客戶端的類型和版本信息。
比如某瓣電影的網頁,假如我們沒有加上請求頭的話,向網站發送請求是會直接報錯的(代碼還是上面的代碼,只換了一個網址)。如下圖:
這時候我們就需要加上請求頭來偽裝我們的爬蟲程序。一般情況下,我們只需要加上一個user-agent,來偽裝我們是瀏覽器,而不是一個爬蟲程序。所以我們要在代碼中加上請求頭,請求頭里添加上user-agent偽裝我們的程序。
運行結果:
官網源代碼如下圖:
發送POST請求
HTTP 的 POST 請求是用于提交數據到服務器進行處理的請求方法。與 GET 請求不同,POST 請求通常不會在 URL 中包含數據,而是將數據包含在請求體中。這使得 POST 請求更適合于發送大量數據或敏感數據(如密碼),因為數據不會在 URL 中暴露。還有比如大部分網頁點贊或者評論等等都是post請求。
我們用下面這個網站來測試post請求。
運行結果如下(可以看到在form表單里有我們發送的數據。):
3. urllib.error模塊
urllib.error
模塊用于處理urllib.request
模塊拋出的異常。當網絡請求出現錯誤時,如連接超時、服務器無響應等,urllib.request
會拋出異常,這時可以使用urllib.error
模塊中的異常類來捕獲和處理這些異常。
4. urllib.parse模塊
urllib.parse
模塊提供了處理URL的功能,如解析URL、構建查詢參數等。
上面已經用過urlencode()這個方法了,接下來再說一下quote()和unquote()方法。
quote()對url地址中的中文進行編碼,類似于urlencode()方法。
unquote()對url地址進行解碼,將編碼后的字符串轉為普通的Unicode字符串。
data = '%E5%92%8C%E5%B9%B3'
result = parse.unquote(data)
print(result) # 運行結果: 和平
requests庫
requests庫支持各種HTTP請求方法,包括GET、POST、PUT、DELETE等,功能非常強大,也是我們寫爬蟲程序中最常用的庫,下面來介紹一些它的使用方法。首先安裝requests庫,終端輸入:pip install requests
注意:由于上面講urllib庫的時候已經講過get請求,post請求等講過的我就不講了,直接教大家使用這個第三方庫,有不同的地方我再講。
1. 發送GET請求
響應頭(Response Headers)包含了關于服務器如何處理請求和返回資源的元數據。這些響應頭對于調試、了解資源屬性和配置緩存等非常有用。響應頭信息用response對象的headers屬性就可以獲取。
2. 發送POST請求
3.?設置請求頭
4.?處理JSON數據
當服務器返回JSON格式的數據時,我們可以使用response.json()
方法將其直接解析為Python對象,這樣就不需要使用python中的json庫來把字符串轉為python中的對象了。
不了解json數據的可以這樣理解:用了json方法后,長的和python中列表或者字典一樣的字符串就轉變為了列表或者字典,可以讓我們直接用python方法提取信息。
今天就先講到這里,下一篇文章會講一下requests庫的更多用法,包括會話保持(Session)、SSL證書驗證、文件上傳、代理設置等稍微高級一點的用法。