題外話:
《Pi Network 免費挖礦國外熱門項目 一個π幣大約值3元到10元》相信過去BTC的人,信不信未來的PI,瞭解一下,唯一一個高度與之持平的項目
HTTP 工作原理
超文本傳輸協議(Hypertext Transfer Protocol,簡稱HTTP)是應用層協議。HTTP 是一種請求/響應式的協議,即一個客戶端與服務器建立連接後,向服務器發送一個請求;服務器接到請求後,給予相應的響應信息。
HTTP 協議採用請求/響應模型。客戶端向服務器發送一個請求報文,服務器以一個狀態作爲響應。
以下是 HTTP 請求/響應的流程:
- 客戶端連接到web服務器:HTTP 客戶端與web服務器建立一個 TCP 連接;
- 客戶端向服務器發起 HTTP 請求:通過已建立的TCP 連接,客戶端向服務器發送一個請求報文;
- 服務器接收 HTTP 請求並返回 HTTP 響應:服務器解析請求,定位請求資源,服務器將資源副本寫到 TCP 連接,由客戶端讀取;
- 釋放 TCP 連接:若connection 模式爲close,則服務器主動關閉TCP 連接,客戶端被動關閉連接,釋放TCP 連接;若connection 模式爲keepalive,則該連接會保持一段時間,在該時間內可以繼續接收請求;
- 客戶端瀏覽器解析HTML內容:客戶端將服務器響應的 html 文本解析並顯示;
例如:在瀏覽器地址欄鍵入URL,按下回車之後會經歷以下流程:
1、瀏覽器向 DNS 服務器請求解析該 URL 中的域名所對應的 IP 地址;
2、解析出 IP 地址後,根據該 IP 地址和默認端口 80,和服務器建立 TCP 連接;
3、瀏覽器發出讀取文件(URL 中域名後面部分對應的文件)的HTTP 請求,該請求報文作爲 TCP 三次握手的第三個報文的數據發送給服務器;
4、服務器對瀏覽器請求作出響應,並把對應的 html 文本發送給瀏覽器;
5、釋放 TCP 連接;
6、瀏覽器將該 html 文本並顯示內容;
HTTP 無狀態性
HTTP 協議是無狀態的(stateless)。也就是說,同一個客戶端第二次訪問同一個服務器上的頁面時,服務器無法知道這個客戶端曾經訪問過,服務器也無法分辨不同的客戶端。HTTP 的無狀態特性簡化了服務器的設計,使服務器更容易支持大量併發的HTTP 請求。
HTTP 持久連接
HTTP1.0 使用的是非持久連接,主要缺點是客戶端必須爲每一個待請求的對象建立並維護一個新的連接,即每請求一個文檔就要有兩倍RTT 的開銷。因爲同一個頁面可能存在多個對象,所以非持久連接可能使一個頁面的下載變得十分緩慢,而且這種短連接增加了網絡傳輸的負擔。HTTP1.1 使用持久連接keepalive,所謂持久連接,就是服務器在發送響應後仍然在一段時間內保持這條連接,允許在同一個連接中存在多次數據請求和響應,即在持久連接情況下,服務器在發送完響應後並不關閉TCP 連接,而客戶端可以通過這個連接繼續請求其他對象。
HTTP/1.1 協議的持久連接有兩種方式:
● 非流水線方式:客戶在收到前一個響應後才能發出下一個請求;
● 流水線方式:客戶在收到 HTTP 的響應報文之前就能接着發送新的請求報文;
請求報文的具體例子:
Remote Address:116.57.254.104:80 Request URL:http://hr.tencent.com/ Request Method:GET Status Code:200 OK Request Headers GET / HTTP/1.1 Host: hr.tencent.com Connection: keep-alive Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36 Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4 Cookie: pgv_pvi=2098703360; PHPSESSID=bc7onl0dojbsatscsfv79pds77; pgv_info=ssid=s1454606128; pgv_pvid=926725350; ts_uid=4084753309 Response Header HTTP/1.1 200 OK Server: nginx Date: Mon, 26 Jan 2015 01:09:10 GMT Content-Type: text/html;charset=utf-8 Content-Length: 3631 Connection: keep-alive X-Powered-By: PHP/5.3.10 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Vary: Accept-Encoding Content-Encoding: gzip
格式化上面的請求報文,方便閱讀
Remote Address:116.57.254.104:80
Request URL:http://hr.tencent.com/
Request Method:GET
Status Code:200 OK
Request Headers
GET / HTTP/1.1
Host: hr.tencent.com
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4
Cookie: pgv_pvi=2098703360; PHPSESSID=bc7onl0dojbsatscsfv79pds77; pgv_info=ssid=s1454606128; pgv_pvid=926725350; ts_uid=4084753309
Response Header
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 26 Jan 2015 01:09:10 GMT
Content-Type: text/html;charset=utf-8 Content-Length: 3631
Connection: keep-alive
X-Powered-By: PHP/5.3.10
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Encoding: gzip
也就是我們谷歌瀏覽器F12常看到的信息格式
從這些報文可以清楚知道請求報文(Request Headers)發送了什麼,響應報文(Response Headers)迴應了什麼東西
例如
GET / HTTP/1.1
請求方法 GET 表示一個讀取請求,將從服務器獲得網頁數據,/表示URL 的路徑,URL 總是以/開頭,/就表示首頁,最後的HTTP/1.1 指示採用的 HTTP 協議版本是 1.1;請求域名如下所示:
Host: hr.tencent.com
響應報文如下:
HTTP/1.1 200 OK
響應頭部可能包括的內容如下(擴展)
Cache-Control
指定了服務器和客戶端在交互時遵循的緩存機制,即是否要留下緩存頁面數據。 一般在使用瀏覽器訪問時,都會在計算機本地留下緩存頁面,相當於是瀏覽器中的頁面保存和下載選項。但是爬蟲就是爲了從網絡上爬取數據,所以幾乎不會從緩存中讀取數據。所以在設置的時候要側重從服務器請求數據而非加載緩存。
no-cache:客戶端告訴服務器,自己不要讀取緩存,要向服務器發起請求。
no-store:同時也是響應頭的參數,請求和響應都禁⽌止緩存,即不存儲。
max-age=0:表示當訪問過此網頁後的多少秒內再次訪問,只加載緩存,而不去服務器請求,在爬蟲時一般就寫0秒 。
一般爬蟲就使用以上幾個參數,其他的參數都是接受緩存的,所以就不列出了。
User-Agent
中文名用戶代理,服務器從此處知道客戶端的操作系統類型和版本,電腦CPU類型,瀏覽器 種類版本,瀏覽器渲染引擎,等等。這是爬蟲當中最最重要的一個請求頭參數,所以一定要僞造,甚⾄至多個。如果不進行僞造,而直接使用各種爬蟲框架中自定義的user-agent,很容易被封禁。
Accept
指定客戶端可以接受的內容類型,比如文本,圖片,應用等等,內容的先後排序表示客戶端接收的先後次序,每種類型之間用逗號隔開。 其中,對於每一種內容類型,分號 ; 後⾯面會加一個 q=0.6 這樣的 q 值,表示該種類型被客戶端喜歡接受的程度,如果沒有表示 q=1,數值越高,客戶端越喜歡這種類型。 爬蟲的時候,一般會僞造若干,將想要找的文字,圖片放在前面,其他的放在後面,最後一定 加上/;q=0.8。
Accept-Language
客戶端可以接受的語⾔言類型,參數值規範和 accept的很像。一般就接收中文和英文,有其他語言需求自行添加。
Accept-Encoding
客戶端接收編碼類型,一些網絡壓縮格式:Accept-Encoding: gzip, deflate, sdch
。相對來說,deflate是一種過時的壓縮格式,現在常用的是gzip
Accept-Charset
指的是規定好服務器處理表單數據所接受的字符集,也就是說,客戶端瀏覽器告訴服務器自己的表單數據的字符集類型,用以正確接收。若沒有定義,則默認值爲unknown
。如果服務器沒有包含此種字符集,就無法正確接收。一般情況下,在爬蟲時不定義該屬性,如果定義,例子如下: Accept-Charset:gb2312,gbk;q=0.7,utf-8;q=0.7,*;q=0.7
Referer
瀏覽器上次訪問的網頁url,uri。由於http協議的無記憶性,服務器可從這裏瞭解到客戶端訪問的前後路徑,並做一些判斷,如果⼀一次訪問的 url 不能從前一次訪問的頁面上跳轉獲得, 在一定程度上說明了請求頭有可能僞造。
DNT
是 do not track 的縮寫,告訴服務器,瀏覽器客戶端是否禁止第三方網站追蹤。這一條主要是用來保護瀏覽器用戶隱私的,通過此功能,用戶可以檢測到跨站跟蹤、cookie跟蹤等等。 在爬蟲時一般都是禁止的。數字1代表禁止追蹤,0代表接收追蹤,null代表空置,沒有規定。
Connection
請求頭的 header字段指的是當 client 瀏覽器和 server 通信時對於長鏈接如何處理。由於http請求是無記憶性的,長連接指的是在 client 和server 之間建立一個通道,方便兩者之間進行多次數據傳輸,而不用來回傳輸數據。有 close,keep-alive 等幾種賦值,close表示不想建立長連接在操作完成後關閉鏈接,而keep-alive 表示希望保持暢通來回傳輸數據。 爬蟲時一般都建立一個長鏈接。
Proxy-Connection
當使用代理服務器的時候,這個就指明瞭代理服務器是否使用長鏈接。但是,數據在從client 到代理服務器,和從代理服務器到被請求的服務器之間如果存在信息差異的話,會造成信息請 求不到,但是在大多數情況下,都還是能夠成立的。
Pragma
防止頁面被緩存, 和 cache-control類似的一個字段,一般爬蟲都寫成 no-cache。
Cookie
同樣是一個比較關鍵的字段,Cookie是 client 請求服務器時,服務器會返回一個鍵值對樣的數據給瀏覽器,下一次瀏覽器再訪問這個域名下的網頁時,就需要攜帶這些鍵值對數據在 Cookie中,用來跟蹤瀏覽器用戶的訪問前後路徑。 在爬蟲時,根據前次訪問得到 cookie數據,然後添加到下⼀一次的訪問請求頭中。
Host
訪問的服務器器主機名,比如百度的 www.baidu.com。這個值在爬蟲時可以從 訪問的 URI 中獲 得。
If-Modified-Since
只有當所請求的內容在指定的日期之後又經過修改才返回它,否則返回304。其目的是爲了提高訪問效率。但是在爬蟲時,不設置這個值,而在增量爬取時才設置一個這樣的值,用以更新信息。
Authorization
當客戶端接收到來自WEB服務器的 WWW-Authenticate 響應時,該頭部來回應自己的身份驗證信息給WEB服務器。主要是授權驗證,確定符合服務器的要求。這個在爬蟲時按需而定。
整理總結報文格式:
HTTP 請求報文格式
HTTP 請求報文由請求行、請求頭部、空行 和 請求包體 4 個部分組成,如下圖所示:
下面對請求報文格式進行簡單的分析:
請求行:
請求行由方法字段、URL 字段 和HTTP 協議版本字段 3 個部分組成,他們之間使用空格隔開。常用的 HTTP 請求方法有 GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT;
● GET:當客戶端要從服務器中讀取某個資源時,使用GET 方法。GET 方法要求服務器將URL 定位的資源放在響應報文的數據部分,回送給客戶端,即向服務器請求某個資源。使用GET 方法時,請求參數和對應的值附加在 URL 後面,利用一個問號(“?”)代表URL 的結尾與請求參數的開始,傳遞參數長度受限制。例如,/index.jsp?id=100&op=bind。
● POST:當客戶端給服務器提供信息較多時可以使用POST 方法,POST 方法向服務器提交數據,比如完成表單數據的提交,將數據提交給服務器處理。GET 一般用於獲取/查詢資源信息,POST 會附帶用戶數據,一般用於更新資源信息。POST 方法將請求參數封裝在HTTP 請求數據中,以名稱/值的形式出現,可以傳輸大量數據;
請求頭部:
請求頭部由關鍵字/值對組成,每行一對,關鍵字和值用英文冒號“:”分隔。請求頭部通知服務器有關於客戶端請求的信息,典型的請求頭有:
● User-Agent:產生請求的瀏覽器類型;
● Accept:客戶端可識別的響應內容類型列表;星號 “ * ” 用於按範圍將類型分組,用 “ */* ” 指示可接受全部類型,用“ type/* ”指示可接受 type 類型的所有子類型;
● Accept-Language:客戶端可接受的自然語言;
● Accept-Encoding:客戶端可接受的編碼壓縮格式;
● Accept-Charset:可接受的應答的字符集;
● Host:請求的主機名,允許多個域名同處一個IP 地址,即虛擬主機;
● connection:連接方式(close 或 keepalive);
● Cookie:存儲於客戶端擴展字段,向同一域名的服務端發送屬於該域的cookie;
空行:
- 最後一個請求頭之後是一個空行,發送回車符和換行符,通知服務器以下不再有請求頭;
請求包體:
- 請求包體不在 GET 方法中使用,而是在POST 方法中使用。POST 方法適用於需要客戶填寫表單的場合。與請求包體相關的最常使用的是包體類型 Content-Type 和包體長度 Content-Length;
HTTP 響應報文格式
HTTP 響應報文由狀態行、響應頭部、空行 和 響應包體 4 個部分組成,如下圖所示:
下面對響應報文格式進行簡單的分析:
狀態行:
狀態行由 HTTP 協議版本字段、狀態碼和狀態碼的描述文本 3 個部分組成,他們之間使用空格隔開;
狀態碼由三位數字組成,第一位數字表示響應的類型,常用的狀態碼有五大類如下所示:
- 1xx:表示服務器已接收了客戶端請求,客戶端可繼續發送請求;
- 2xx:表示服務器已成功接收到請求並進行處理;
- 3xx:表示服務器要求客戶端重定向;
- 4xx:表示客戶端的請求有非法內容;
- 5xx:表示服務器未能正常處理客戶端的請求而出現意外錯誤;
狀態碼描述文本有如下取值:
- 200 OK:表示客戶端請求成功;
- 400 Bad Request:表示客戶端請求有語法錯誤,不能被服務器所理解;
- 401 Unauthonzed:表示請求未經授權,該狀態代碼必須與 WWW-Authenticate 報頭域一起使用;
- 403 Forbidden:表示服務器收到請求,但是拒絕提供服務,通常會在響應正文中給出不提供服務的原因;
- 404 Not Found:請求的資源不存在,例如,輸入了錯誤的URL;
- 500 Internal Server Error:表示服務器發生不可預期的錯誤,導致無法完成客戶端的請求;
- 503 Service Unavailable:表示服務器當前不能夠處理客戶端的請求,在一段時間之後,服務器可能會恢復正常;
響應頭部:
響應頭可能包括:
Location:Location響應報頭域用於重定向接受者到一個新的位置。例如:客戶端所請求的頁面已不存在原先的位置,爲了讓客戶端重定向到這個頁面新的位置,服務器端可以發回Location響應報頭後使用重定向語句,讓客戶端去訪問新的域名所對應的服務器上的資源;
Server:Server 響應報頭域包含了服務器用來處理請求的軟件信息及其版本。它和 User-Agent 請求報頭域是相對應的,前者發送服務器端軟件的信息,後者發送客戶端軟件(瀏覽器)和操作系統的信息。
Vary:指示不可緩存的請求頭列表;
Connection:連接方式;
對於請求來說:close(告訴 WEB 服務器或者代理服務器,在完成本次請求的響應後,斷開連接,不等待本次連接的後續請求了)。keepalive(告訴WEB服務器或者代理服務器,在完成本次請求的響應後,保持連接,等待本次連接的後續請求);
對於響應來說:close(連接已經關閉); keepalive(連接保持着,在等待本次連接的後續請求); Keep-Alive:如果瀏覽器請求保持連接,則該頭部表明希望WEB 服務器保持連接多長時間(秒);例如:Keep-Alive:300;
WWW-Authenticate:WWW-Authenticate響應報頭域必須被包含在401 (未授權的)響應消息中,這個報頭域和前面講到的Authorization 請求報頭域是相關的,當客戶端收到 401 響應消息,就要決定是否請求服務器對其進行驗證。如果要求服務器對其進行驗證,就可以發送一個包含了Authorization 報頭域的請求;
空行:
最後一個響應頭部之後是一個空行,發送回車符和換行符,通知服務器以下不再有響應頭部。
響應包體:
服務器返回給客戶端的文本信息;
HTTP 工作原理
HTTP 協議採用請求/響應模型。客戶端向服務器發送一個請求報文,服務器以一個狀態作爲響應。
以下是 HTTP 請求/響應的步驟:
● 客戶端連接到web服務器:HTTP 客戶端與web服務器建立一個 TCP 連接;
● 客戶端向服務器發起 HTTP 請求:通過已建立的TCP 連接,客戶端向服務器發送一個請求報文;
● 服務器接收 HTTP 請求並返回 HTTP 響應:服務器解析請求,定位請求資源,服務器將資源副本寫到 TCP 連接,由客戶端讀取;
● 釋放 TCP 連接:若connection 模式爲close,則服務器主動關閉TCP 連接,客戶端被動關閉連接,釋放TCP 連接;若connection 模式爲keepalive,則該連接會保持一段時間,在該時間內可以繼續接收請求;
● 客戶端瀏覽器解析HTML內容:客戶端將服務器響應的 html 文本解析並顯示;