新聞中心
在瀏覽網(wǎng)站的過程中我們經(jīng)常會(huì)遇到需要登錄的情況,有些頁(yè)面只有登錄之后我們才可以訪問,而且登錄之后可以連續(xù)訪問很多次網(wǎng)站,但是有時(shí)候過一段時(shí)間就會(huì)需要重新登錄。還有一些網(wǎng)站有時(shí)在我們打開瀏覽器的時(shí)候就自動(dòng)登錄了,而且很長(zhǎng)的時(shí)間都不會(huì)失效,這種情況又是為什么?其實(shí)這里面涉及到 Session 和 Cookies 的相關(guān)知識(shí),本節(jié)我們就來揭開它們的神秘面紗。
1. 靜態(tài)網(wǎng)頁(yè)和動(dòng)態(tài)網(wǎng)頁(yè)
在開始之前我們需要先了解一下靜態(tài)網(wǎng)頁(yè)和動(dòng)態(tài)網(wǎng)頁(yè)的概念。
還是前文中的示例代碼,內(nèi)容如下:
This is a Demo
Hello World
Hello, this is a paragraph.
Python資源分享qun 784758214 ,內(nèi)有安裝包,PDF,學(xué)習(xí)視頻,這里是Python學(xué)習(xí)者的聚集地,零基礎(chǔ),進(jìn)階,都?xì)g迎
這是最基本的 HTML 代碼,我們將其保存為一個(gè) html 文件,然后把它放在某臺(tái)具有固定公網(wǎng) IP 的主機(jī)上,主機(jī)上裝上 Apache 或 Nginx 等服務(wù)器,這樣這臺(tái)主機(jī)就可以作為服務(wù)器了,其他人便可以通過訪問服務(wù)器看到這個(gè)頁(yè)面了,這就搭建了一個(gè)最簡(jiǎn)單的網(wǎng)站。
這種網(wǎng)頁(yè)的內(nèi)容是 HTML 代碼編寫的,文字、圖片等內(nèi)容均是通過寫好的 HTML 代碼來指定的,這種頁(yè)面叫做靜態(tài)網(wǎng)頁(yè)。
這種網(wǎng)頁(yè)加載速度快,編寫簡(jiǎn)單,但是存在很大的缺陷,如可維護(hù)性差,不能根據(jù) URL 靈活多變地顯示內(nèi)容等,例如我們想要給這個(gè)網(wǎng)頁(yè)的 URL 傳入一個(gè) name 參數(shù),讓其在網(wǎng)頁(yè)中顯示出來,是無法做到的。
所以動(dòng)態(tài)網(wǎng)頁(yè)應(yīng)運(yùn)而生,它可以動(dòng)態(tài)解析 URL 中參數(shù)的變化,關(guān)聯(lián)數(shù)據(jù)庫(kù)并動(dòng)態(tài)地呈現(xiàn)不同的頁(yè)面內(nèi)容,非常靈活多變,我們現(xiàn)在遇到的大多數(shù)網(wǎng)站都是動(dòng)態(tài)網(wǎng)站,它們不再是一個(gè)簡(jiǎn)單的 HTML,而是可能由 JSP、PHP、Python 等語言編寫的,功能相比靜態(tài)網(wǎng)頁(yè)強(qiáng)大和豐富太多太多。
動(dòng)態(tài)網(wǎng)站還可以實(shí)現(xiàn)用戶登錄注冊(cè)的功能,再回到開篇提到的問題,很多頁(yè)面是需要登錄之后才可以查看的,按照一般的邏輯來說,我們輸入用戶名密碼登錄之后,肯定是拿到了一種類似憑證的東西,有了它我們才能保持登錄狀態(tài),才能訪問登錄之后才能看到的頁(yè)面。
那么這種神秘的憑證到底是什么呢?其實(shí)它就是 Session 和 Cookies 共同產(chǎn)生的結(jié)果,下面我們來一探它們的究竟。
2. 無狀態(tài)HTTP
在了解 Session 和 Cookies 之前,我們還需要了解 HTTP 的一個(gè)特點(diǎn),叫做無狀態(tài)。
HTTP 的無狀態(tài)是指 HTTP 協(xié)議對(duì)事務(wù)處理是沒有記憶能力的,也就是說服務(wù)器不知道客戶端是什么狀態(tài)。當(dāng)我們向服務(wù)器發(fā)送一個(gè) Requset 后,服務(wù)器解析此 Request,然后返回對(duì)應(yīng)的 Response,服務(wù)器負(fù)責(zé)完成這個(gè)過程,而且這個(gè)過程是完全獨(dú)立的,服務(wù)器不會(huì)記錄前后狀態(tài)的變化,也就是缺少狀態(tài)記錄,這意味著如果后續(xù)需要處理需要前面的信息,則它必須要重傳,這也導(dǎo)致了需要額外傳遞一些前面的重復(fù) Request 才能獲取后續(xù) Response,然而這種效果顯然不是我們想要的。為了保持前后狀態(tài),我們肯定不能將前面的請(qǐng)求全部重傳一次,這太浪費(fèi)資源了,對(duì)于這種需要用戶登錄的頁(yè)面來說,更是棘手。
所以,這時(shí)候,兩個(gè)用于保持 HTTP 連接狀態(tài)的技術(shù)就出現(xiàn)了,它們分別是 Session 和 Cookies,Session 在服務(wù)端,也就是網(wǎng)站的服務(wù)器,用來保存用戶的會(huì)話信息,Cookies 在客戶端,也可以理解為瀏覽器端,有了 Cookies,瀏覽器在下次訪問網(wǎng)頁(yè)時(shí)會(huì)自動(dòng)附帶上它發(fā)送給服務(wù)器,服務(wù)器通過識(shí)別 Cookies 并鑒定出是哪個(gè)用戶,然后再判斷用戶是否是登錄狀態(tài),然后返回對(duì)應(yīng)的 Response。
所以我們可以理解為 Cookies 里面保存了登錄的憑證,有了它我們只需要在下次請(qǐng)求攜帶 Cookies 發(fā)送 Request 而不必重新輸入用戶名、密碼等信息重新登錄了。
因此在爬蟲中,有時(shí)候處理需要登錄才能訪問的頁(yè)面時(shí),我們一般會(huì)直接將登錄成功后獲取的 Cookies 放在 Request Headers 里面直接請(qǐng)求,而不必重新模擬登錄。
好,大體了解什么是 Session 和 Cookies 之后,我們來詳細(xì)剖析一下它們的原理。
2. Session
Session,即會(huì)話,其本來的含義是指有始有終的一系列動(dòng)作/消息,比如打電話時(shí)從拿起電話撥號(hào)到掛斷電話這中間的一系列過程可以稱之為一個(gè) Session。
而在 Web 中 Session 對(duì)象用來存儲(chǔ)特定用戶會(huì)話所需的屬性及配置信息。這樣,當(dāng)用戶在應(yīng)用程序的 Web 頁(yè)之間跳轉(zhuǎn)時(shí),存儲(chǔ)在 Session 對(duì)象中的變量將不會(huì)丟失,而是在整個(gè)用戶會(huì)話中一直存在下去。當(dāng)用戶請(qǐng)求來自應(yīng)用程序的 Web 頁(yè)時(shí),如果該用戶還沒有會(huì)話,則 Web 服務(wù)器將自動(dòng)創(chuàng)建一個(gè) Session 對(duì)象。當(dāng)會(huì)話過期或被放棄后,服務(wù)器將終止該會(huì)話。
3. Cookies
Cookie,有時(shí)也用其復(fù)數(shù)形式 Cookies,指某些網(wǎng)站為了辨別用戶身份、進(jìn)行 Session 跟蹤而儲(chǔ)存在用戶本地終端上的數(shù)據(jù)。
會(huì)話維持
那么利用 Cookies 我們是怎樣來保持狀態(tài)的呢?當(dāng)客戶端第一次請(qǐng)求服務(wù)器時(shí),服務(wù)器會(huì)返回一個(gè) Headers 中帶有 Set-Cookie 字段的 Response 給客戶端,用來標(biāo)記是哪一個(gè)用戶,客戶端瀏覽器會(huì)把Cookies 保存起來。當(dāng)瀏覽器下一次再請(qǐng)求該網(wǎng)站時(shí),瀏覽器會(huì)把此Cookies 放到 Request Headers 一起提交給服務(wù)器,Cookies 攜帶了 Session ID 信息,服務(wù)器檢查該 Cookies 即可找到對(duì)應(yīng)的 Session 是什么,然后再判斷 Session 來以此來辨認(rèn)用戶狀態(tài)。
所以我們?cè)诘卿浤硞€(gè)網(wǎng)站的時(shí)候,登錄成功后服務(wù)器會(huì)告訴客戶端設(shè)置哪些 Cookies 信息,在后續(xù)訪問頁(yè)面時(shí)客戶端會(huì)把 Cookies 發(fā)送給服務(wù)器,服務(wù)器再找到對(duì)應(yīng)的 Session 加以判斷,如果 Session 中的某些設(shè)置登錄狀態(tài)的變量是有效的,那就證明用戶是處于登錄狀態(tài)的,即可返回登錄之后才可以查看的網(wǎng)頁(yè)內(nèi)容,瀏覽器進(jìn)行解析便可以看到了。
反之,如果傳給服務(wù)器的 Cookies 是無效的,或者 Session 已經(jīng)過期了,我們將不能繼續(xù)訪問頁(yè)面,可能會(huì)收到錯(cuò)誤的 Response 或者跳轉(zhuǎn)到登錄頁(yè)面重新登錄。
所以 Cookies 和 Session 需要配合,一個(gè)處于客戶端,一個(gè)處于服務(wù)端,二者共同協(xié)作,就實(shí)現(xiàn)了登錄會(huì)話控制。
屬性結(jié)構(gòu)
接下來我們來看看 Cookies 都有哪些內(nèi)容,在這里以知乎為例,在瀏覽器開發(fā)者工具中打開 Application 選項(xiàng)卡,然后在左側(cè)會(huì)有一個(gè) Storage 部分,最后一項(xiàng)即為 Cookies,將其點(diǎn)開,可以看到類似如下內(nèi)容,這些就是 Cookies,如圖 2-14 所示:
圖 2-14 Cookies 列表
我們可以看到 Cookies 有一個(gè)個(gè)條目,每個(gè)條目我們可以稱之為 Cookie,取單數(shù)形式。它有這么幾個(gè)屬性:
- Name,即該 Cookie 的名稱。Cookie 一旦創(chuàng)建,名稱便不可更改
- Value,即該 Cookie 的值。如果值為 Unicode 字符,需要為字符編碼。如果值為二進(jìn)制數(shù)據(jù),則需要使用 BASE64 編碼
- 。Max Age,即該 Cookie 失效的時(shí)間,單位秒,也常和 Expires 一起使用,通過它可以計(jì)算出其有效時(shí)間。Max Age 如果為正數(shù),則該Cookie 在 Max Age 秒之后失效。如果為負(fù)數(shù),則關(guān)閉瀏覽器時(shí)Cookie 即失效,瀏覽器也不會(huì)以任何形式保存該 Cookie。Path,即該 Cookie 的使用路徑。如果設(shè)置為 /path/,則只有路徑為 /path/ 的頁(yè)面可以訪問該 Cookie。如果設(shè)置為 /,則本域名下的所有頁(yè)面都可以訪問該 Cookie。
- Domain,即可以訪問該 Cookie 的域名。例如如果設(shè)置為 .zhihu.com,則所有以 zhihu.com,結(jié)尾的域名都可以訪問該Cookie。
- Size字段,即此 Cookie 的大小。
- Http字段,即 Cookie 的 httponly 屬性。若此屬性為 true,則只有在 HTTP Headers 中會(huì)帶有此 Cookie 的信息,而不能通過 document.cookie 來訪問此 Cookie。
- Secure,即該 Cookie 是否僅被使用安全協(xié)議傳輸。安全協(xié)議。安全協(xié)議有 HTTPS,SSL 等,在網(wǎng)絡(luò)上傳輸數(shù)據(jù)之前先將數(shù)據(jù)加密。默認(rèn)為 false。以上便是 Cookies 的基本結(jié)構(gòu)。
會(huì)話Cookie、持久Cookie
表面意思來說,會(huì)話 Cookie 就是把 Cookie 放在瀏覽器內(nèi)存里,瀏覽器在關(guān)閉之后該 Cookie 即失效,持久 Cookie 則會(huì)保存到客戶端的硬盤中,下次還可以繼續(xù)使用,用于長(zhǎng)久保持用戶登錄狀態(tài)。
其實(shí)嚴(yán)格來說沒有會(huì)話 Cookie 和持久 Cookie 之分,它只是由 Cookie 的 Max Age 或 Expires 字段決定了過期的時(shí)間,通過它瀏覽器可以計(jì)算出其有效時(shí)間。Max Age 如果為正數(shù),則該 Cookie 在 Max Age 秒之后失效,如果 Max Age 特別大,那就會(huì)保存非常長(zhǎng)的時(shí)間。如果為負(fù)數(shù),則關(guān)閉瀏覽器時(shí) Cookie 即失效,瀏覽器也不會(huì)以任何形式保存該 Cookie。
所以一些持久化登錄的網(wǎng)站其實(shí)就是把 Cookie 的有效時(shí)間和 Session 有效期設(shè)置得比較長(zhǎng),下次我們?cè)僭L問頁(yè)面時(shí)仍然攜帶之前的 Cookies 就可以直接保持登錄狀態(tài)。Python資源分享qun 784758214 ,內(nèi)有安裝包,PDF,學(xué)習(xí)視頻,這里是Python學(xué)習(xí)者的聚集地,零基礎(chǔ),進(jìn)階,都?xì)g迎
4. 常見誤區(qū)
在談?wù)?Session 機(jī)制的時(shí)候,常常聽到這樣一種誤解“只要關(guān)閉瀏覽器,Session 就消失了”,這種理解是錯(cuò)誤的,可以想象一下會(huì)員卡的例子,除非顧客主動(dòng)對(duì)店家提出銷卡,否則店家絕對(duì)不會(huì)輕易刪除顧客的資料。對(duì) Session 來說也是一樣的,除非程序通知服務(wù)器刪除一個(gè) Session,否則服務(wù)器會(huì)一直保留,比如程序一般都是在我們做注銷操作的時(shí)候才去刪除 Session。
但是當(dāng)我們關(guān)閉瀏覽器時(shí),瀏覽器不會(huì)主動(dòng)在關(guān)閉之前通知服務(wù)器它將要關(guān)閉,所以服務(wù)器根本不會(huì)有機(jī)會(huì)知道瀏覽器已經(jīng)關(guān)閉,之所以會(huì)有這種錯(cuò)覺,是大部分 Session 機(jī)制都使用會(huì)話 Cookie 來保存 Session ID 信息,而關(guān)閉瀏覽器后 Cookies 就消失了,再次連接服務(wù)器時(shí)也就無法找到原來的 Session。如果服務(wù)器設(shè)置的 Cookies 被保存到硬盤上,或者使用某種手段改寫瀏覽器發(fā)出的 HTTP 請(qǐng)求頭,把原來的 Cookies 發(fā)送給服務(wù)器,則再次打開瀏覽器仍然能夠找到原來的 Session ID,依舊還是可以保持登錄狀態(tài)的。
而且恰恰是由于關(guān)閉瀏覽器不會(huì)導(dǎo)致 Session 被刪除,這就需要服務(wù)器為 Seesion 設(shè)置一個(gè)失效時(shí)間,當(dāng)距離客戶端上一次使用 Session 的時(shí)間超過這個(gè)失效時(shí)間時(shí),服務(wù)器就可以認(rèn)為客戶端已經(jīng)停止了活動(dòng),才會(huì)把 Session 刪除以節(jié)省存儲(chǔ)空間。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
網(wǎng)站題目:Python3網(wǎng)絡(luò)爬蟲實(shí)戰(zhàn)-18、Session和Cookies-創(chuàng)新互聯(lián)
文章地址:http://www.ef60e0e.cn/article/dgpgoo.html