Python 爬蟲十六式 – 第一式:HTTP協議

Connor_Zhang發表於2019-03-02

HTTP:偉大而又無聞的協議

學習一時爽,一直學習一直爽!

  Hello,大家好啊,我是Connor,一個從無到有的技術小白。有的人一說什麼是HTTP協議就犯愁,寫東西的時候也沒想過什麼是HTTP協議,只是知道HTTP協議是用來網頁傳輸的,但是再深究一點就不明白了,所以今天我們來講一講什麼是HTTP協議。

今天不當講也得講了

1.HTTP 與 HTTPS

   1.1 什麼是HTTP協議

  超文字傳輸協議(HTTP,HyperText Transfer Protocol) 是網際網路上應用最為廣泛的一種網路協議。所有的WWW檔案都必須遵守這個標準。設計HTTP最初的目的是為了提供一種釋出和接收HTML頁面的方法。
HTTP協議是用於從WWW伺服器傳輸超文字到本地瀏覽器的傳送協議。它可以使瀏覽器更加高效,使網路傳輸減少。它不僅保證計算機正確快速地傳輸超文字文件,還確定傳輸文件中的哪一部分,以及哪部分內容首先顯示(如文字先於圖形)等。

  HTTP是一個應用層協議,由請求和響應構成,是一個標準的客戶端伺服器模型。

  一次HTTP請求的基本流程一般是,在建立TCP連線後,由客戶端向服務端發起一次請求 request ,而伺服器在接收到以後返回給客戶端一個響應 response 。所以我們看到的HTTP請求內容一般就分為請求和響應兩部分。

  HTTP協議通常承載於TCP協議之上,預設HTTP的埠號為80。有時也承載於TLS或SSL協議層之上,這個時候,就成了我們常說的HTTPS,稍後我們會詳細說HTTP和HTTPS的區別。

   1.2 HTTP協議的特點

  1. http協議支援客戶端/服務端模式,也是一種請求/響應模式的協議。

  2. 無連線。所謂的無連線就是伺服器收到了客戶端的請求之後,響應完成並收到客戶端的應答之後,即斷開連線。限制每次的連線只處理一次請求。從而節省傳輸時間。

  3. 無狀態。HTTP協議是無狀態的,也就是說每一次HTTP請求之間都是相互獨立的,沒有聯絡的,服務端不知道客戶端具體的狀態。比如客戶端訪問一次網頁之後關閉瀏覽器,然後再一次啟動瀏覽器,再訪問該網站,伺服器是不知道客戶關閉了一次瀏覽器的。這樣設計的原因是因為Web伺服器一般需要面對很多瀏覽器的併發訪問,為了提高Web伺服器對併發訪問的處理能力,在設計HTTP協議時規定Web伺服器傳送HTTP應答報文和文件時,不儲存發出請求的Web瀏覽器程式的任何狀態資訊

  4. 簡單快捷:所謂的簡單快捷是指客戶端向伺服器請求服務時,一般來說只需要傳輸請求方法和路徑,就能進行訪問。

  5. 靈活:客戶端可以通過HTTP協議傳輸任意型別的資料,包括但不限於文字,圖片,視訊等

   1.3 HTTP與HTTPS的區別

  HTTP大家都知道是什麼東西了,那什麼是HTTPS呢?HTTPS是以安全為目標的HTTP通道,簡單講是HTTP的安全版,即HTTP下加入SSL層,HTTPS的安全基礎是SSL,承載於SSL協議層之上。因此加密的詳細內容就需要SSL。

區別 HTTP HTTPS
安全性 不安全 安全
是否需要證照 不需要 需要
傳輸方式 明文傳輸 加密傳輸
預設埠 80 443

  HTTPS和HTTP相比的主要優勢就是體現在它的安全性上,它的缺點也很明顯,體現在它的行能和技術方面,具體的優缺點我們不再多說,大家可以自行體會。


2.HTTP 請求

  每一個HTTP請求都由三部分組成,分別是:請求行、請求報頭、請求正文。

   2.1 請求行

  請求行一般由請求方法url路徑協議版本組成,如下所示:

GET www.baidu.com HTTP/1.1

  通過上面我們可以看到請求行分了三個部分,其中GET就是請求行中的請求方法,https://www.baidu.com 就是請求行中的url路徑, HTTP/1.1就是它的協議版本。

   2.2 請求報頭(請求頭)

  請求頭遵循以下格式:

名字:空格 + 值

   常用的請求頭的屬性如下:

屬性名 作用
Host 指定的請求資源的域名(主機和埠號)。HTTP請求必須包含HOST,否則系統會以400狀態碼返回。
User-Agent 簡稱UA,內容包含發出請求的使用者資訊,通常UA包含瀏覽者的資訊,主要是瀏覽器的名稱版本和所用的作業系統。這個UA頭不僅僅是使用瀏覽器才存在,只要使用了基於HTTP協議的客戶端軟體都會傳送,無論是手機端還是PDA等,這個UA頭是辨別客戶端所用裝置的重要依據。
Accept 告訴伺服器可以接受的檔案格式。
Cookie 告訴瀏覽器Cookie資訊
Cache-Control 指定請求和響應遵循的快取機制。
Referer 頁面跳轉處,表明請求來自於哪個URL,使用者是從該哪個頁面訪問到當前頁面的。
Content-Length 內容長度。
Content-Range 響應的資源範圍。可以在每次請求中標記請求的資源範圍,在連線斷開重連時,客戶端只請求該資源未下載的部分,而不是重新請求整個資源,實現斷點續傳。
Accept-Encoding 指定所能夠接受的編碼方式
Accept-Language 指瀏覽器可以接受的語言種類 en、en-us指英語 zh、zh-cn指中文。
Connection 客戶端與伺服器連結型別,keep-alive:保持連結,close:關閉連結。

   當然這些知識列舉出了平時常用的一些請求頭屬性,有些網站也會使用自定義的屬性,會使用諸如su,x-index等各種非常用屬性之外的屬性,非常容易鑑別。

   2.3 請求正文

   請求正文通常只有使用POST方式進行請求的時候才會有請求正文,如果使用GET請求的話,是不會有請求正文的,具體情況將會在後面的GET與POST請求處細說。

   2.4 HTTP請求方法

HTTP協議中定義的請求方法有以下幾種:

序號 方法 描述
1 GET 請求指定的頁面資訊,並返回實體主體。
2 HEAD 類似於get請求,只不過返回的響應中沒有具體的內容,用於獲取報頭
3 POST 向指定資源提交資料進行處理請求(例如提交表單或者上傳檔案)。資料被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。
4 PUT 從客戶端向伺服器傳送的資料取代指定的文件的內容。
5 DELETE 請求伺服器刪除指定的頁面。
6 CONNECT HTTP/1.1協議中預留給能夠將連線改為管道方式的代理伺服器。
7 OPTIONS 允許客戶端檢視伺服器的效能。
8 TRACE 回顯伺服器收到的請求,主要用於測試或診斷。

雖然HTTP請求中定義的方法有這麼多種,但是我們平常使用的基本只有GETPOST兩種方法,而且大部分網站都是禁用掉了除GETPOST外其他的方法。

因為其他幾種方法通過GET或者POST都能實現,而且對於網站來說更加的安全和可控。

  • GET

    其實簡單來說,GET方法一般用來負責獲取資料,或者將一些簡短的資料放到URL引數中傳遞到伺服器。比POST更加高效和方便。

  • POST

    由於GET方法最多在url中攜帶1024位元組資料,且將資料放到URL中傳遞太不安全,資料量大時URL也會變得冗長。所以傳遞資料量大或者安全性要求高的資料的時候,最好使用POST方法來傳遞資料。


3.HTTP響應

  每一個HTTP請求也都由三部分組成和請求行類似,分別是:響應行、響應報頭、響應正文。

   3.1 響應行

  狀態行由HTTP協議版本號, 狀態碼, 狀態訊息三部分組成。如下所示:

HTTP/1.1 200 OK

上面我們看到了響應行的內容,其中HTTP/1.1是協議版本號,200是狀態碼,OK是狀態訊息。

   2.2響應正文

  響應頭格式和請求頭格式相同,遵循以下格式:

名字:空格 + 值

  常用的響應頭屬性如下:

屬性名 作用
Allow 伺服器支援哪些請求方法(如GET、POST等)
Date 表示訊息傳送的時間,時間的描述格式為格林威治時間
Set-Cookie 用於把cookie傳送到客戶端瀏覽器,每一個寫入cookie都會生成一個Set-Cookie
Expires 可以理解為過期時間,當到期之後瀏覽器會從伺服器重新獲取,放棄本地快取文件
Content-Type WEB伺服器告訴客戶端自己響應的物件的型別和字符集
Content-Encoding 文件的編碼(Encode)方法。只有在解碼之後才可以得到Content-Type頭指定的內容型別。利用gzip壓縮文件能夠顯著地減少HTML文件的下載時間
Content-Length 指明實體正文的長度,以位元組方式儲存的十進位制數字來表示
Location 用於重定向一個新的位置,包含新的URL地址。表示客戶應當到哪裡去提取文件
Refresh 表示瀏覽器應該在多少時間之後重新整理文件,以秒計

   3.3 響應正文

  伺服器返回的資料。

  3.4 狀態碼

當客戶端向服務端發起一次請求後,服務端在返回的響應頭中會包含一個HTTP狀態碼,以表明這一次請求的狀態。下面是一些常見的狀態碼:

  • 200 – 請求成功
  • 301 – 資源(網頁等)被永久轉移到其它URL
  • 404 – 請求的資源(網頁等)不存在
  • 500 – 內部伺服器錯誤

HTTP的狀態碼是由三位數字來表示的,由第一位數字來表示狀態碼的型別,一般來說有五種型別:

分類 分類描述
1** 資訊,伺服器收到請求,需要請求者繼續執行操作
2** 成功,操作被成功接收並處理
3** 重定向,需要進一步的操作以完成請求
4** 客戶端錯誤,請求包含語法錯誤或無法完成請求
5** 伺服器錯誤,伺服器在處理請求的過程中發生了錯誤

以下是詳細的狀態碼列表:

狀態碼 狀態碼英文名稱 中文描述
100 Continue 繼續。客戶端應繼續其請求
101 Switching Protocols 切換協議。伺服器根據客戶端的請求切換協議。只能切換到更高階的協議,例如,切換到HTTP的新版本協議
200 OK 請求成功。一般用於GET與POST請求
201 Created 已建立。成功請求並建立了新的資源
202 Accepted 已接受。已經接受請求,但未處理完成
203 Non-Authoritative Information 非授權資訊。請求成功。但返回的meta資訊不在原始的伺服器,而是一個副本
204 No Content 無內容。伺服器成功處理,但未返回內容。在未更新網頁的情況下,可確保瀏覽器繼續顯示當前文件
205 Reset Content 重置內容。伺服器處理成功,使用者終端(例如:瀏覽器)應重置文件檢視。可通過此返回碼清除瀏覽器的表單域
206 Partial Content 部分內容。伺服器成功處理了部分GET請求
300 Multiple Choices 多種選擇。請求的資源可包括多個位置,相應可返回一個資源特徵與地址的列表用於使用者終端(例如:瀏覽器)選擇
301 Moved Permanently 永久移動。請求的資源已被永久的移動到新URI,返回資訊會包括新的URI,瀏覽器會自動定向到新URI。今後任何新的請求都應使用新的URI代替
302 Found 臨時移動。與301類似。但資源只是臨時被移動。客戶端應繼續使用原有URI
303 See Other 檢視其它地址。與301類似。使用GET和POST請求檢視
304 Not Modified 未修改。所請求的資源未修改,伺服器返回此狀態碼時,不會返回任何資源。客戶端通常會快取訪問過的資源,通過提供一個頭資訊指出客戶端希望只返回在指定日期之後修改的資源
305 Use Proxy 使用代理。所請求的資源必須通過代理訪問
306 Unused 已經被廢棄的HTTP狀態碼
307 Temporary Redirect 臨時重定向。與302類似。使用GET請求重定向
400 Bad Request 客戶端請求的語法錯誤,伺服器無法理解
401 Unauthorized 請求要求使用者的身份認證
402 Payment Required 保留,將來使用
403 Forbidden 伺服器理解請求客戶端的請求,但是拒絕執行此請求
404 Not Found 伺服器無法根據客戶端的請求找到資源(網頁)。通過此程式碼,網站設計人員可設定”您所請求的資源無法找到”的個性頁面
405 Method Not Allowed 客戶端請求中的方法被禁止
406 Not Acceptable 伺服器無法根據客戶端請求的內容特性完成請求
407 Proxy Authentication Required 請求要求代理的身份認證,與401類似,但請求者應當使用代理進行授權
408 Request Time-out 伺服器等待客戶端傳送的請求時間過長,超時
409 Conflict 伺服器完成客戶端的PUT請求是可能返回此程式碼,伺服器處理請求時發生了衝突
410 Gone 客戶端請求的資源已經不存在。410不同於404,如果資源以前有現在被永久刪除了可使用410程式碼,網站設計人員可通過301程式碼指定資源的新位置
411 Length Required 伺服器無法處理客戶端傳送的不帶Content-Length的請求資訊
412 Precondition Failed 客戶端請求資訊的先決條件錯誤
413 Request Entity Too Large 由於請求的實體過大,伺服器無法處理,因此拒絕請求。為防止客戶端的連續請求,伺服器可能會關閉連線。如果只是伺服器暫時無法處理,則會包含一個Retry-After的響應資訊
414 Request-URI Too Large 請求的URI過長(URI通常為網址),伺服器無法處理
415 Unsupported Media Type 伺服器無法處理請求附帶的媒體格式
416 Requested range not satisfiable 客戶端請求的範圍無效
417 Expectation Failed 伺服器無法滿足Expect的請求頭資訊
500 Internal Server Error 伺服器內部錯誤,無法完成請求
501 Not Implemented 伺服器不支援請求的功能,無法完成請求
502 Bad Gateway 充當閘道器或代理的伺服器,從遠端伺服器接收到了一個無效的請求
503 Service Unavailable 由於超載或系統維護,伺服器暫時的無法處理客戶端的請求。延時的長度可包含在伺服器的Retry-After頭資訊中
504 Gateway Time-out 充當閘道器或代理的伺服器,未及時從遠端伺服器獲取請求
505 HTTP Version not supported 伺服器不支援請求的HTTP協議的版本,無法完成處理

4. URI、URL、URN

   4.1 URI、URL、URN的定義

  什麼是URI? 什麼是URL? 什麼又是URN?三個概念中我們接觸的最多的就是URL,那URN和URI又是什麼東西呢?怎麼以前沒聽過呢?我們來看他們三個的定義:

  URI:Uniform Resource Identifier,即統一資源標誌符,用來唯一的標識一個資源。

  URL:Uniform Resource Locator,統一資源定位符。即URL可以用來標識一個資源,而且還指明瞭如何locate這個資源。

  URN:Uniform Resource Name,統一資源命名。即通過名字來表示資源的。

下面我們重點說一下URL的格式,再來說一下URI、URL、URN的區別:

   4.2 URL的格式:

  一個完整的URL包含協議名稱,主機名稱(IP或者域名)、埠號(沒寫埠號預設 為80埠)、路徑、查詢字串和錨這6個部分。比如:

http//www.quanshuwang.com:80/modules/article/search.php?searchkey=abcd&searchtype=1&page=2#top

  http是它的協議名稱。
  www.quanshuwang.com就是它的域名。
  /modules/article/search.php是它的路徑。
  :80是它的埠號,80是http的預設埠號,一般情況下會隱藏的。
  searchtype=1&page=2是它的查詢字串。
  #top是它的錨點,用來定位的,比如說回到頂部。

   4.3 URI,URL,URN之間的關係:

Python 爬蟲十六式 – 第一式:HTTP協議

   上圖中我們可以看到,URL和URN是URI的子集,URI是統一資源標誌符,而URL除了有標識的功能之外,還有定位的功能,可以用來描述資源的具體位置,還指明瞭獲取資源所採用的協議。

   URN也是URL的一種表現形式,它和URL的區別就是與資源的位置無關,正式由於位置的無關性,被某個URN標識的資源在位置發生變化時,其URI可以保持不變。但是我們在平時的使用中幾乎沒有用URN的,更多的用的是URL。所以URL和URN都是URI的一種擴充套件,一種表現形式,URL和URN肯定是一個URI,但是URI不一定是URN或URL。


5. Cookie

  Cookie有時也用其複數形式 Cookies,英文是餅乾的意思。指某些網站為了辨別使用者身份、進行 session 跟蹤而儲存在使用者本地終端上的資料(通常經過加密)。

  Cookie其實就是由伺服器發給客戶端的特殊資訊,而這些資訊以文字檔案的方式存放在客戶端,然後客戶端每次向伺服器傳送請求的時候都會帶上這些特殊的資訊。 伺服器在接收到Cookie以後,會驗證Cookie的資訊,以此來辨別使用者的身份,當然如果有需求,伺服器還可以根據需要對Cookie的內容進行修改。

   5.1 Cookie的作用

  Cookie其實是HTTP請求頭的擴充套件部分,由於HTTP協議是無狀態的協議,所以為了在網頁上實現登陸之類的需求,所以擴充套件了Cookie這樣的功能。

  每一次HTTP請求在資料交換完畢之後就會關閉連線,所以下一次HTTP請求就無法讓服務端得知你和上一次請求的關係。而使用了Cookie之後,你在第一次登陸之類的請求成功之後,伺服器會在Response的頭資訊中給你返回Cookie資訊,你下一次訪問的時候帶上這個Cookie資訊,則伺服器就能識別你為上一次成功登陸的使用者。

   5.2 Cookie的內容

  Cookie一般儲存的格式為json格式,由一些屬性組成。

  - name:Cookie的名稱
  - value:Cookie的值
  - domain:可以使用此Cookie的域名
  - path:可以使用此Cookie的頁面路徑
  - expires/Max-Age:此Cookie的超時時間
  - secure:設定是否只能通過https來傳遞此條Cookie

   5.3 domain屬性

  域名一般來說分為頂級域名,二級域名,三級域名等等。

  例如baidu.com是一個頂級域名,而www.baidu.com和map.baidu.com就是二級域名,依次類推。

  而在我們的Cookie來說,都有一個domain屬性,這個屬性限制了訪問哪些域名時可以使用這一條Cookie。因為每個網站基本上都會分發Cookie,所以domain屬性就可以讓我們在訪問新浪時不會帶上百度分發給我們的Cookie

  而在同一系的域名中,頂級域名是無法使用其二級域名的Cookie的,也就是說訪問baidu.com的時候是不會帶上map.baidu.com分發的Cookie的,二級域名之間的Cookie也不可以共享。但訪問二級域名時是可以使用頂級域名的Cookie的。

   5.4 path屬性

  path屬性為可以訪問此cookie的頁面路徑。 比如domain是abc.com,path是/test,那麼只有/test路徑下的頁面可以讀取此cookie。

   5.5 expires/Max-Age屬性

  欄位為此cookie超時時間。若設定其值為一個時間,那麼當到達此時間後,此cookie失效。不設定的話預設值是Session,意思是cookie會和session一起失效。當瀏覽器關閉(不是瀏覽器標籤頁,而是整個瀏覽器) 後,此cookie失效。


6. Session

  Session,中文經常翻譯為會話,其本來的含義是指有始有終的一系列動作/訊息,比如打電話時從拿起電話撥號到結束通話電話這中間的一系列過程可以稱之為一個session。這個詞在各個領域都有在使用。

  而我們web領域,一般使用的是其本義,一個瀏覽器視窗從開啟到關閉這個期間

  Session的目的則是,在一個客戶從開啟瀏覽器到關閉瀏覽器這個期間內,發起的所有請求都可以被識別為同一個使用者。而實現的方式則是,在一個客戶開啟瀏覽器開始訪問網站的時候,會生成一個SessionID,這個ID每次的訪問都會帶上,而伺服器會識別這個SessionID並且將與這個SessionID有關的資料儲存在伺服器上。由此來實現客戶端的狀態識別。

  Session與Cookie相反,Session是儲存在伺服器上的資料,只由客戶端傳上來的SessionId來進行判定,所以相對於Cookie,Session的安全性更高。

  一般SessionID會在瀏覽器被關閉時丟棄,或者伺服器會驗證Session的活躍程度,例如30分鐘某一個SessionID都沒有活躍,那麼也會被識別為失效。


以上就是HTTP有關的所有內容了,我是Connor,一個從無到有的技術小白,如果覺得我說的有什麼不對的地方,歡迎指出!我們下期再見。

學習一時爽,一直學習一直爽!


系列文章連線:

Python 爬蟲十六式 – 第二式:urllib 與 urllib3 >>>
Python 爬蟲十六式 – 第三式:Requests的用法 >>>
Python 爬蟲十六式 – 第四式:使用Xpath提取網頁內容 >>>
Python 爬蟲十六式 – 第五式:BeautifulSoup,美味的湯 >>>
Python 爬蟲十六式 – 第六式:JQuery的假兄弟-pyquery >>>
Python 爬蟲十六式 – 第七式:正則的藝術 >>>
Python 爬蟲十六式 – 第八式:例項解析-全書網 >>>

相關文章