天天看點

爬蟲基礎之會話和Cookies

在浏覽網站的過程中,我們經常會遇到需要登入的情況,有些頁面隻有登入之後才可以通路,而且登入之後可以連續通路很多次網站,但是有時候過一段時間就需要重新登入。還有一些網站,在打開浏覽器時就自動登入了,而且很長時間都不會失效,這種情況又是為什麼?其實這裡面涉及會話和Cookies的相關知識,本節就來揭開它們的神秘面紗。

1. 靜态網頁和動态網頁

在開始之前,我們需要先了解一下靜态網頁和動态網頁的概念。這裡還是前面的示例代碼,内容如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>This is a Demo</title>
    </head>
    <body>
        <div id="container">
            <div class="wrapper">
                <h2 class="title">Hello World</h2>
                <p class="text">Hello, this is a paragraph.</p>
            </div>
        </div>
    </body>
</html>
           

這是最基本的HTML代碼,我們将其儲存為一個.html檔案,然後把它放在某台具有固定公網IP的主機上,主機上裝上Apache或Nginx等伺服器,這樣這台主機就可以作為伺服器了,其他人便可以通過通路伺服器看到這個頁面,這就搭建了一個最簡單的網站。

這種網頁的内容是HTML代碼編寫的,文字、圖檔等内容均通過寫好的HTML代碼來指定,這種頁面叫作靜态網頁。它加載速度快,編寫簡單,但是存在很大的缺陷,如可維護性差,不能根據URL靈活多變地顯示内容等。例如,我們想要給這個網頁的URL傳入一個

name

參數,讓其在網頁中顯示出來,是無法做到的。

是以,動态網頁應運而生,它可以動态解析URL中參數的變化,關聯資料庫并動态呈現不同的頁面内容,非常靈活多變。我們現在遇到的大多數網站都是動态網站,它們不再是一個簡單的HTML,而是可能由JSP、PHP、Python等語言編寫的,其功能比靜态網頁強大和豐富太多了。

此外,動态網站還可以實作使用者登入和注冊的功能。再回到開頭提到的問題,很多頁面是需要登入之後才可以檢視的。按照一般的邏輯來說,輸入使用者名和密碼登入之後,肯定是拿到了一種類似憑證的東西,有了它,我們才能保持登入狀态,才能通路登入之後才能看到的頁面。

其實它就是會話和Cookies共同産生的結果,下面我們來一探究竟。

2. 無狀态HTTP

在了解會話和Cookies之前,我們還需要了解HTTP的一個特點,叫作無狀态。

HTTP的無狀态是指HTTP協定對事務處理是沒有記憶能力的,也就是說伺服器不知道用戶端是什麼狀态。當我們向伺服器發送請求後,伺服器解析此請求,然後傳回對應的響應,伺服器負責完成這個過程,而且這個過程是完全獨立的,伺服器不會記錄前後狀态的變化,也就是缺少狀态記錄。這意味着如果後續需要處理前面的資訊,則必須重傳,這導緻需要額外傳遞一些前面的重複請求,才能擷取後續響應,然而這種效果顯然不是我們想要的。為了保持前後狀态,我們肯定不能将前面的請求全部重傳一次,這太浪費資源了,對于這種需要使用者登入的頁面來說,更是棘手。

這時兩個用于保持HTTP連接配接狀态的技術就出現了,它們分别是會話和Cookies。會話在服務端,也就是網站的伺服器,用來儲存使用者的會話資訊;Cookies在用戶端,也可以了解為浏覽器端,有了Cookies,浏覽器在下次通路網頁時會自動附帶上它發送給伺服器,伺服器通過識别Cookies并鑒定出是哪個使用者,然後再判斷使用者是否是登入狀态,然後傳回對應的響應。

我們可以了解為Cookies裡面儲存了登入的憑證,有了它,隻需要在下次請求攜帶Cookies發送請求而不必重新輸入使用者名、密碼等資訊重新登入了。

是以在爬蟲中,有時候處理需要登入才能通路的頁面時,我們一般會直接将登入成功後擷取的Cookies放在請求頭裡面直接請求,而不必重新模拟登入。

好了,了解會話和Cookies的概念之後,我們在來詳細剖析它們的原理。

(1) 會話

在Web中,會話對象用來存儲特定使用者會話所需的屬性及配置資訊。這樣,當使用者在應用程式的Web頁之間跳轉時,存儲在會話對象中的變量将不會丢失,而是在整個使用者會話中一直存在下去。當使用者請求來自應用程式的Web頁時,如果該使用者還沒有會話,則Web伺服器将自動建立一個會話對象。當會話過期或被放棄後,伺服器将終止該會話。

(2) Cookies

Cookies指某些網站為了辨識使用者身份、進行會話跟蹤而存儲在使用者本地終端上的資料。

會話維持

那麼,我們怎樣利用Cookies保持狀态呢?當用戶端第一次請求伺服器時,伺服器會傳回一個請求頭中帶有

Set-Cookie

字段的響應給用戶端,用來标記是哪一個使用者,用戶端浏覽器會把Cookies儲存起來。當浏覽器下一次再請求該網站時,浏覽器會把此Cookies放到請求頭一起送出給伺服器,Cookies攜帶了會話ID資訊,伺服器檢查該Cookies即可找到對應的會話是什麼,然後再判斷會話來以此來辨認使用者狀态。

在成功登入某個網站時,伺服器會告訴用戶端設定哪些Cookies資訊,在後續通路頁面時用戶端會把Cookies發送給伺服器,伺服器再找到對應的會話加以判斷。如果會話中的某些設定登入狀态的變量是有效的,那就證明使用者處于登入狀态,此時傳回登入之後才可以檢視的網頁内容,浏覽器再進行解析便可以看到了。

反之,如果傳給伺服器的Cookies是無效的,或者會話已經過期了,我們将不能繼續通路頁面,此時可能會收到錯誤的響應或者跳轉到登入頁面重新登入。

是以,Cookies和會話需要配合,一個處于用戶端,一個處于服務端,二者共同協作,就實作了登入會話控制。

屬性結構

接下來,我們來看看Cookies都有哪些内容。這裡以知乎為例,在浏覽器開發者工具中打開Application頁籤,然後在左側會有一個Storage部分,最後一項即為Cookies,将其點開,如圖所示,這些就是Cookies。

爬蟲基礎之會話和Cookies

可以看到,這裡有很多條目,其中每個條目可以稱為Cookie。它有如下幾個屬性。

  • Name:該Cookie的名稱。一旦建立,該名稱便不可更改。
  • Value:該Cookie的值。如果值為Unicode字元,需要為字元編碼。如果值為二進制資料,則需要使用BASE64編碼。
  • Domain:可以通路該Cookie的域名。例如,如果設定為.zhihu.com,則所有以zhihu.com,結尾的域名都可以通路該Cookie。
  • Max Age:該Cookie失效的時間,機關為秒,也常和Expires一起使用,通過它可以計算出其有效時間。Max Age如果為正數,則該Cookie在Max Age秒之後失效。如果為負數,則關閉浏覽器時Cookie即失效,浏覽器也不會以任何形式儲存該Cookie。
  • Path:該Cookie的使用路徑。如果設定為/path/,則隻有路徑為/path/的頁面可以通路該Cookie。如果設定為/,則本域名下的所有頁面都可以通路該Cookie。
  • Size字段:此Cookie的大小。
  • HTTP字段:Cookie的

    httponly

    屬性。若此屬性為

    true

    ,則隻有在HTTP頭中會帶有此Cookie的資訊,而不能通過

    document.cookie

    來通路此Cookie。
  • Secure:該Cookie是否僅被使用安全協定傳輸。安全協定有HTTPS和SSL等,在網絡上傳輸資料之前先将資料加密。預設為

    false

會話Cookie和持久Cookie

從表面意思來說,會話Cookie就是把Cookie放在浏覽器記憶體裡,浏覽器在關閉之後該Cookie即失效;持久Cookie則會儲存到用戶端的硬碟中,下次還可以繼續使用,用于長久保持使用者登入狀态。

其實嚴格來說,沒有會話Cookie和持久Cookie之分,隻是由Cookie的Max Age或Expires字段決定了過期的時間。是以,一些持久化登入的網站其實就是把Cookie的有效時間和會話有效期設定得比較長,下次我們再通路頁面時仍然攜帶之前的Cookie,就可以直接保持登入狀态。

3. 常見誤區

在談論會話機制的時候,常常聽到這樣一種誤解“隻要關閉浏覽器,會話就消失了”,這種了解是錯誤的。可以想象一下會員卡的例子,除非顧客主動對店家提出銷卡,否則店家絕對不會輕易删除顧客的資料。對會話來說,也是一樣,除非程式通知伺服器删除一個會話,否則伺服器會一直保留。比如,程式一般都是在我們做登出操作時才去删除會話。

但是當我們關閉浏覽器時,浏覽器不會主動在關閉之前通知伺服器它将要關閉,是以伺服器根本不會有機會知道浏覽器已經關閉。之是以會有這種錯覺,是因為大部分會話機制都使用會話Cookie來儲存會話ID資訊,而關閉浏覽器後Cookies就消失了,再次連接配接伺服器時,也就無法找到原來的會話了。如果伺服器設定的Cookies儲存到硬碟上,或者使用某種手段改寫浏覽器發出的HTTP請求頭,把原來的Cookies發送給伺服器,則再次打開浏覽器,仍然能夠找到原來的會話 ID,依舊還是可以保持登入狀态的。

而且恰恰是由于關閉浏覽器不會導緻會話被删除,這就需要伺服器為會話設定一個失效時間,當距離用戶端上一次使用會話的時間超過這個失效時間時,伺服器就可以認為用戶端已經停止了活動,才會把會話删除以節省存儲空間。

原文連結:https://cuiqingcai.com/5487.html

繼續閱讀