天天看點

HTTP基本原理

HTTP基本原理

在本節我們會詳細了解 HTTP 的基本原理,了解在浏覽器中敲入一個 URL 到擷取網頁内容發生了一個怎樣的過程,了解了這些内容,有助于去進一步了解爬蟲的基本原理。

1. URI、URL

在了解 HTTP 之前我們先了解一下 URI 和 URL。我們經常會聽到 URI 和 URL 兩個術語,URI 全稱為 Uniform Resource Identifier,即統一資源标志符,URL 全稱為 Universal Resource Locator,即統一資源定位符。

舉例來說,https://github.com/favicon.ico,這是 GitHub 的網站圖示連結,它是一個 URL,也是一個 URI,即有這樣的一個圖示資源,我們用 URL/URI 來唯一指定了它的通路方式,這其中包括了通路協定 https、通路路徑/即根目錄,資源名稱 favicon.ico,通過這樣的一個連結我們便可以從網際網路上找到這個資源,這就是 URL/URI。

URL 是 URI 的子集,也就是說每個 URL 都是 URI,但不是每個 URI 都是 URL。那麼怎樣的 URI 不是 URL 呢?URI 還包括一個子類叫做 URN,它的全稱為 Universal Resource Name,即統一資源名稱。URN 隻命名資源而不指定如何定位資源,如 urn:isbn:0451450523,它指定了一本書的 ISBN,可以唯一辨別這一本書,但是沒有指定到哪裡定位這本書,這就是 URN,URL、URN、URI 的關系可以用圖表示如下:

HTTP基本原理

URL、URN、URI 關系圖

但是在目前的網際網路,URN 的使用非常少,是以幾乎所有的 URI 都是 URL,是以一般的網頁連結我們可以稱之為 URL,也可以稱之為 URI,我個人習慣稱之為 URL。

2. 超文本

接下來我們再了解一個概念,超文本。超文本英文名稱叫做 Hypertext,我們在浏覽器裡面看到的網頁就是超文本解析而成的,其網頁源代碼是一系列 HTML 代碼,裡面包含了一系列标簽,如 img 顯示圖檔,p 指定顯示段落等,浏覽器解析這些标簽後便形成了我們平常看到的網頁,而這網頁的源代碼 HTML 就可以稱作超文本。

例如我們在 Chrome 浏覽器裡面打開任意一個頁面,如淘寶首頁,右鍵點選檢查,或按下快捷鍵 F12 即可打開浏覽器的開發者工具,這時我們在 Elements 頁籤即可看到目前網頁的源代碼,這些源代碼都是超文本,如圖所示:

HTTP基本原理

 源代碼

3. HTTP、HTTPS

我們在前面了解了 URI 和 URL,例如淘寶的首頁:https://www.taobao.com/,在URL 的開頭會有 http 或 https,這個就是通路資源需要的協定類型,有時我們還會看到 ftp、sftp、smb 開頭的 URL,那麼這裡的 ftp、sftp、smb 都是指的協定類型。在爬蟲中,我們抓取的頁面通常就是 http 或 https 協定的,我們在這裡首先來了解一下這兩個協定的含義。

HTTP 的全稱是 Hyper Text Transfer Protocol,中文名叫做超文本傳輸協定,HTTP 協定是用于從網絡傳輸超文本資料到本地浏覽器的傳送協定,它能保證傳送高效而準确地傳送超文本文檔。HTTP 由網際網路協會(World Wide Web Consortium)和 Internet 工作小組IETF(Internet Engineering Task Force)共同合作制定的規範,目前廣泛使用的是 HTTP 1.1 版本。

HTTPS 的全稱是 Hyper Text Transfer Protocol over Secure Socket Layer,是以安全為目标的 HTTP 通道,簡單講是 HTTP 的安全版,即 HTTP 下加入 SSL 層,簡稱為 HTTPS。

HTTPS 的安全基礎是 SSL,是以通過它傳輸的内容都是經過 SSL 加密的,它的主要作用可以分為兩種:

是建立一個資訊安全通道,來保證資料傳輸的安全。

确認網站的真實性,凡是使用了 https 的網站,都可以通過點選浏覽器位址欄的鎖頭标志來檢視網站認證之後的真實資訊,也可以通過 CA 機構頒發的安全簽章來查詢。

現在越來越多的網站和 APP 都已經向 HTTPS 方向發展。例如:

蘋果公司強制所有 iOS App 在 2017 年 1 月 1 日 前全部改為使用 HTTPS 加密,否則 APP 就無法在應用商店上架。

谷歌從 2017 年 1 月推出的 Chrome 56 開始,對未進行 HTTPS 加密的網址連結亮出風險提示,即在位址欄的顯著位置提醒使用者“此網頁不安全”。

騰訊微信小程式的官方需求文檔要求背景使用 HTTPS 請求進行網絡通信,不滿足條件的域名和協定無法請求。

而某些網站雖然使用了 HTTPS 協定還是會被浏覽器提示不安全,例如我們在 Chrome 浏覽器裡面打開 12306,連結為:https://www.12306.cn/,這時浏覽器就會提示“您的連接配接不是私密連接配接”這樣的話,如圖所示:

HTTP基本原理

12306 頁面

這是因為12306 的 CA 證書是中國鐵道部自己頒發給自己的,而這個證書是不被官方機構認可的,是以這裡證書驗證就不會通過而提示這樣的話,但是實際上它的資料傳輸依然是經過 SSL 加密的。我們如果要爬取這樣的站點就需要設定忽略證書的選項,否則會提示 SSL 連結錯誤,在後文會進行詳細說明。

4. HTTP請求過程

我們在浏覽器中輸入一個URL,回車之後便會在浏覽器中觀察到頁面内容,實際上這個過程是浏覽器向網站所在的伺服器發送了一個 Request,即請求,網站伺服器接收到這個Request 之後進行處理和解析,然後傳回對應的一個 Response,即響應,然後傳回給浏覽器,Response裡面就包含了頁面的源代碼等内容,浏覽器再對其進行解析便将網頁呈現了出來,模型如圖所示:

HTTP基本原理

模型圖

此處用戶端即代表我們自己的 PC 或手機浏覽器,伺服器即要通路的網站所在的伺服器。

為了更直覺地地說明這個的過程,我們在這裡用 Chrome 浏覽器的開發者模式下的 Network 監聽元件來做下示範,它可以顯示通路目前請求網頁時發生的所有網絡請求和響應。

打開 Chrome 浏覽器,右鍵點選檢查,或按下快捷鍵 F12 即可打開浏覽器的開發者工具,我們在這裡通路百度:http://www.baidu.com/,輸入該 URL,敲擊回車通路這個頁面,觀察一下在這個過程中發生了怎樣的網絡請求,這時我們可以看到在 Network 頁面的下方出現了一個個的條目,那麼這一個條目就代表一次發送 Request 和接收 Response 的過程,如圖所示:

HTTP基本原理

 Network 面闆

我們觀察第一個網絡請求,即 www.baidu.com,如圖所示:

HTTP基本原理

網絡請求記錄

這一個條目的各列分别代表:

第一列 Name,即 Request 的名稱。一般會用URL的最後一部分内容當做名稱。

第二列 Status,即 Response 的狀态碼。這裡顯示為 200,代表 Response 是正常的,通過狀态碼我們可以判斷發送了 Request 之後是否得到了正常的 Response。

第三列 Type,即 Request 請求的文檔類型。這裡為 document,代表我們這次請求的是一個 HTML 文檔,内容就是一些 HTML 代碼。

第四列 Initiator,即請求源。用來标記 Request 是由哪個對象或程序發起的。

第五列 Size,即從伺服器下載下傳的檔案和請求的資源大小。如果是從緩存中取得的資源則該列會顯示 from cache。

第六列 Time,即發起 Request 到擷取到 Response 所用的總時間。

第七列 Timeline,即網絡請求的可視化瀑布流。

我們點選這個條目即可看到其更詳細的資訊,如圖所示:

HTTP基本原理

詳細資訊

首先是General 部分,Request URL 為 Request 的 URL,Request Method 為請求的方法,Status Code 為響應狀态碼,Remote Address 為遠端伺服器的位址和端口,Referrer Policy 為 Referrer 判别政策。

再繼續往下看可以看到有一個 Response Headers 和一個 Request Headers,這分别代表響應頭和請求頭,請求頭裡面帶有許多請求資訊,例如浏覽器辨別、Cookies、Host 等資訊,這是 Request 的一部分,伺服器會根據請求頭内的資訊判斷請求是否合法,進而作出對應的響應,傳回 Response,那麼在圖中看到的 Response Headers 就是 Response 的一部分,例如其中包含了伺服器的類型、文檔類型、日期等資訊,浏覽器接受到 Response 後,會解析響應内容,進而呈現網頁内容。

下面我們分别來介紹一下請求 Request 和響應 Response 都包含了哪些内容,在這裡進行對其組成進行總結:

5. Request

Request,即請求,由用戶端向服務端發出。可以将 Request 劃分為四部分内容:Request Method、Request URL、Request Headers、Request Body,即請求方式、請求連結、請求頭、請求體。

Request Method

請求方式,請求方式常見的有兩種類型,GET 和 POST。

我們在浏覽器中直接輸入一個 URL 并回車,這便發起了一個 GET 請求,請求的參數會直接包含到 URL 裡,例如百度搜尋 Python,這就是一個 GET 請求,連結為:https://www.baidu.com/s?wd=Python,URL中包含了請求的參數資訊,這裡參數 wd 就是要搜尋的關鍵字。POST 請求大多為表單送出發起,如一個登入表單,輸入使用者名密碼,點選登入按鈕,這通常會發起一個 POST 請求,其資料通常以 Form Data 即表單的形式傳輸,不會展現在 URL 中。

GET 和 POST 請求方法有如下差別:

GET 方式請求中參數是包含在 URL 裡面的,資料可以在 URL 中看到,而 POST 請求的 URL 不會包含這些資料,資料都是通過表單的形式傳輸,會包含在 Request Body 中。

GET 方式請求送出的資料最多隻有 1024 位元組,而 POST 方式沒有限制。

是以一般來說,網站登入驗證的時候,需要送出使用者名密碼,這裡包含了敏感資訊,使用GET方式請求的話密碼就會暴露在URL裡面,造成密碼洩露,是以這裡最好以POST方式發送。

檔案的上傳時,由于檔案内容比較大,也會選用POST方式。

我們平常遇到的絕大部分請求都是 GET 或 POST 請求,另外還有一些請求方式,如 HEAD、PUT、DELETE、OPTIONS、CONNECT、TRACE,我們簡單将其總結如下:

方法描述

GET請求指定的頁面資訊,并傳回實體主體。

HEAD類似于 GET 請求,隻不過傳回的響應中沒有具體的内容,用于擷取報頭。

POST向指定資源送出資料進行處理請求,資料被包含在請求體中。

PUT從用戶端向伺服器傳送的資料取代指定的文檔的内容。

DELETE請求伺服器删除指定的頁面。

CONNECTHTTP/1.1 協定中預留給能夠将連接配接改為管道方式的代理伺服器。

OPTIONS允許用戶端檢視伺服器的性能。

TRACE回顯伺服器收到的請求,主要用于測試或診斷。

本表參考:http://www.runoob.com/http/http-methods.html。

Request URL

顧名思義,就是請求的網址,即統一資源定位符,用 URL 可以唯一确定我們想請求的資源。

Request Headers

請求頭,用來說明伺服器要使用的附加資訊,比較重要的資訊有 Cookie、Referer、User-Agent 等,下面将一些常用的頭資訊說明如下:

Accept,請求報頭域,用于指定用戶端可接受哪些類型的資訊。

Accept-Language,指定用戶端可接受的語言類型。

Accept-Encoding,指定用戶端可接受的内容編碼。

Host,用于指定請求資源的主機 IP 和端口号,其内容為請求URL 的原始伺服器或網關的位置。從 HTTP 1.1 版本開始,Request 必須包含此内容。

Cookie,也常用複數形式Cookies,是網站為了辨識使用者進行 Session 跟蹤而儲存在使用者本地的資料。Cookies 的主要功能就是維持目前通路會話,例如我們輸入使用者名密碼登入了某個網站,登入成功之後伺服器會用 Session 儲存我們的登入狀态資訊,後面我們每次重新整理或請求該站點的其他頁面時會發現都是保持着登入狀态的,在這裡就是 Cookies 的功勞,Cookies 裡有資訊辨別了我們所對應的伺服器的 Session 會話,每次浏覽器在請求該站點的頁面時都會在請求頭中加上 Cookies 并将其發送給伺服器,伺服器通過 Cookies 識别出是我們自己,并且查出目前狀态是登入的狀态,是以傳回的結果就是登入之後才能看到的網頁内容。

Referer,此内容用來辨別這個請求是從哪個頁面發過來的,伺服器可以拿到這一資訊并做相應的處理,如做來源統計、做防盜鍊處理等。

User-Agent,簡稱 UA,它是一個特殊字元串頭,使得伺服器能夠識别客戶使用的作業系統及版本、浏覽器及版本等資訊。在做爬蟲時加上此資訊可以僞裝為浏覽器,如果不加很可能會被識别出為爬蟲。

Content-Type,即 Internet Media Type,網際網路媒體類型,也叫做 MIME 類型,在 HTTP 協定消息頭中,使用它來表示具體請求中的媒體類型資訊。例如 text/html 代表 HTML 格式,image/gif 代表 GIF 圖檔,application/json 代表 Json 類型,更多對應關系可以檢視此對照表:http://tool.oschina.net/commons。

是以,Request Headers 是 Request 等重要組成部分,在寫爬蟲的時候大部分情況都需要設定 Request Headers。

Request Body

即請求體,一般承載的内容是 POST 請求中的 Form Data,即表單資料,而對于 GET 請求 Request Body 則為空。

例如在這裡我登入 GitHub 時捕獲到的 Request 和 Response 如圖所示:

HTTP基本原理

 詳細資訊

在登入之前我們填寫了使用者名和密碼資訊,送出時就這些内容就會以Form Data 的形式送出給伺服器,此時注意 Request Headers 中指定了 Content-Type 為 application/x-www-form-urlencoded,隻有設定 Content-Type 為 application/x-www-form-urlencoded 才會以 Form Data 形式送出,另外我們也可以将 Content-Type 設定為 application/json 來送出 Json 資料,或者設定為 multipart/form-data 來上傳檔案。

下面列出了 Content-Type 和 POST 送出資料方式的關系:

Content-Type送出資料方式

application/x-www-form-urlencodedForm 表單送出

multipart/form-data表單檔案上傳送出

application/json序列化 Json 資料送出

text/xmlXML 資料送出

在爬蟲中如果我們要構造 POST 請求需要注意這幾種 Content-Type,了解各種請求庫的各個參數設定時使用的是哪種 Content-Type,不然可能會導緻 POST 送出後得不到正常的 Response。

以上便是對 Request 各部分内容的解釋。

6. Response

Response,即響應,由服務端傳回給用戶端。Response 可以劃分為三部分,Response Status Code、Response Headers、Response Body。

Response Status Code

響應狀态碼,此狀态碼表示了伺服器的響應狀态,如 200 則代表伺服器正常響應,404 則代表頁面未找到,500 則代表伺服器内部發生錯誤。在爬蟲中,我們可以根據狀态碼來判斷伺服器響應狀态,如判斷狀态碼為 200,則證明成功傳回資料,再進行進一步的處理,否則直接忽略。

下面用表格列出了常見的錯誤代碼及錯誤原因:

狀态碼說明詳情

100繼續請求者應當繼續提出請求。伺服器已收到請求的一部分,正在等待其餘部分。

101切換協定請求者已要求伺服器切換協定,伺服器已确認并準備切換。

200成功伺服器已成功處理了請求。

201已建立請求成功并且伺服器建立了新的資源。

202已接受伺服器已接受請求,但尚未處理。

203非授權資訊伺服器已成功處理了請求,但傳回的資訊可能來自另一來源。

204無内容伺服器成功處理了請求,但沒有傳回任何内容。

205重置内容伺服器成功處理了請求,内容被重置。

206部分内容伺服器成功處理了部分請求。

300多種選擇針對請求,伺服器可執行多種操作。

301永久移動請求的網頁已永久移動到新位置,即永久重定向。

302臨時移動請求的網頁暫時跳轉到其他頁面,即暫時重定向。

303檢視其他位置如果原來的請求是 POST,重定向目标文檔應該通過 GET 提取。

304未修改此次請求傳回的網頁未修改,繼續使用上次的資源。

305使用代理請求者應該使用代理通路該網頁。

307臨時重定向請求的資源臨時從其他位置響應。

400錯誤請求伺服器無法解析該請求。

401未授權請求沒有進行身份驗證或驗證未通過。

403禁止通路伺服器拒絕此請求。

404未找到伺服器找不到請求的網頁。

405方法禁用伺服器禁用了請求中指定的方法。

406不接受無法使用請求的内容響應請求的網頁。

407需要代理授權請求者需要使用代理授權。

408請求逾時伺服器請求逾時。

409沖突伺服器在完成請求時發生沖突。

410已删除請求的資源已永久删除。

411需要有效長度伺服器不接受不含有效内容長度标頭字段的請求。

412未滿足前提條件伺服器未滿足請求者在請求中設定的其中一個前提條件。

413請求實體過大請求實體過大,超出伺服器的處理能力。

414請求 URI 過長請求網址過長,伺服器無法處理。

415不支援類型請求的格式不受請求頁面的支援。

416請求範圍不符頁面無法提供請求的範圍。

417未滿足期望值伺服器未滿足期望請求标頭字段的要求。

500伺服器内部錯誤伺服器遇到錯誤,無法完成請求。

501未實作伺服器不具備完成請求的功能。

502錯誤網關伺服器作為網關或代理,從上遊伺服器收到無效響應。

503服務不可用伺服器目前無法使用。

504網關逾時伺服器作為網關或代理,但是沒有及時從上遊伺服器收到請求。

505HTTP 版本不支援伺服器不支援請求中所用的 HTTP 協定版本。

Response Headers

響應頭,其中包含了伺服器對請求的應答資訊,如 Content-Type、Server、Set-Cookie 等,下面将一些常用的頭資訊說明如下:

Date,辨別 Response 産生的時間。

Last-Modified,指定資源的最後修改時間。

Content-Encoding,指定 Response 内容的編碼。

Server,包含了伺服器的資訊,名稱,版本号等。

Content-Type,文檔類型,指定了傳回的資料類型是什麼,如text/html 則代表傳回 HTML 文檔,application/x-javascript 則代表傳回 JavaScript 檔案,image/jpeg 則代表傳回了圖檔。

Set-Cookie,設定Cookie,Response Headers 中的 Set-Cookie即告訴浏覽器需要将此内容放在 Cookies 中,下次請求攜帶 Cookies 請求。

Expires,指定 Response 的過期時間,使用它可以控制代理伺服器或浏覽器将内容更新到緩存中,如果再次通路時,直接從緩存中加載,降低伺服器負載,縮短加載時間。

Resposne Body

即響應體,最重要的當屬響應體内容了,響應的正文資料都是在響應體中,如請求一個網頁,它的響應體就是網頁的HTML 代碼,請求一張圖檔,它的響應體就是圖檔的二進制資料。是以最主要的資料都包含在響應體中了,我們做爬蟲請求網頁後要解析的内容就是解析響應體,如圖所示:

HTTP基本原理

響應體内容

我們在浏覽器開發者工具中點選 Preview,就可以看到網頁的源代碼,這也就是響應體内容,是解析的目标。

我們在做爬蟲時主要解析的内容就是 Resposne Body,通過 Resposne Body 我們可以得到網頁的源代碼、Json 資料等等,然後從中做相應内容的提取。

以上便是 Response 的組成部分。

下一篇: First article