目錄
一、會話和Cookies
1.1 靜態網頁和動態網頁
1.2 無狀態HTTP
1.3 常見誤區
二、代理的基本原理
2.1 基本原理
2.2 代理的作用
2.3 爬蟲代理
2.4 代理分類
2.5 常見代理設置
一、會話和Cookies
????????大家在瀏覽網站過程中,肯定經常遇到需要登錄的場景。有些頁面限制訪問,只有登錄后才能打開,而且登錄一次后,能連續多次訪問網站。不過,有時候隔了一段時間,就又得重新登錄。還有一些網站更方便,打開瀏覽器就自動完成登錄,很長時間內都不會失效。這究竟是什么原因呢?實際上,這些現象背后,都和會話(Session)以及Cookies的知識有關。接下來這一節,咱們就一起深入了解一下。
1.1 靜態網頁和動態網頁
????????在正式了解會話和Cookies之前,我們得先清楚靜態網頁和動態網頁的概念。這里還是用前面的示例代碼:
<!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協同工作產生的結果。接下來,咱們就深入探究一番。
1.2 無狀態HTTP
????????在深入了解會話和Cookies之前,我們得先掌握HTTP的一個特性,那就是無狀態。
????????所謂HTTP的無狀態,也就是說HTTP協議在處理事務時,沒有記憶的能力。直白點講,服務器是不知道客戶端處于什么狀態的。當我們向服務器發送請求后,服務器會對請求進行解析,然后返回對應的響應。而且這個過程是完全獨立的,服務器不會去記錄前后狀態的變化情況,缺少對狀態的記錄。這就導致了一個問題,如果后續的處理需要用到前面的信息,那就必須重新傳輸,這樣就需要額外地發送一些重復的請求,才能獲取到后續的響應。很明顯,這種情況并不是我們想要的。為了能保持前后狀態的連貫性,我們肯定不能把前面的請求全部再重傳一遍,這樣做太浪費資源了,特別是對于那些需要用戶登錄的頁面來說,這種重傳的方式就更不合適了。
????????在這種情況下,有兩種能夠保持HTTP連接狀態的技術就出現了,它們分別是會話和Cookies。會話是保存在服務端的,也就是網站的服務器上,主要用來保存用戶的會話信息;而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信息了,就像下圖所展示的那樣。
????????這里面有很多條目,每一個條目都可以看作是一個Cookie,它有以下幾個屬性:
??????? - Name:這是Cookie的名稱。一旦創建好了,這個名稱就不能再更改了。
??????? - Value:這是Cookie的值。如果這個值是Unicode字符的話,就需要進行字符編碼;要是值是二進制數據,那就需要用BASE64編碼。
??????? - Domain:指的是可以訪問這個Cookie的域名。比如說,如果設置成了.zhihu.com,那么所有以zhihu.com結尾的域名都可以訪問這個Cookie。
??????? - MaxAge:這是Cookie失效的時間,單位是秒,它經常會和Expires一起使用,通過它可以計算出Cookie的有效時間。當MaxAge是正數的時候,這個Cookie會在MaxAge秒之后失效;要是MaxAge是負數,那么關閉瀏覽器的時候,這個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的MaxAge或者Expires字段來決定的。
????????所以,有些支持持久化登錄的網站,會把Cookie的有效時間和會話的有效期設置得比較長。這樣一來,下次我們再去訪問頁面的時候,只要還帶著之前的Cookie,就可以直接保持登錄狀態了。
1.3 常見誤區
????????在探討會話機制時,不少人存在一個誤解,覺得“只要關閉瀏覽器,會話就會消失”。打個比方,以會員卡為例,通常情況下,除非顧客主動要求店家注銷會員卡,否則店家不會隨意刪除顧客的資料。會話機制也是同樣的道理,除非程序指令服務器刪除會話,不然服務器會一直保存會話數據。比如當我們執行注銷操作時,程序就會刪除對應的會話。
????????當我們關閉瀏覽器時,瀏覽器并不會在關閉前告知服務器它即將關閉,因此服務器無從得知瀏覽器已經關閉。大家之所以會產生“關閉瀏覽器會話就消失”這種錯覺,是因為大多數會話機制采用會話Cookie來存儲會話ID信息。關閉瀏覽器后,這些Cookie就會消失,再次連接服務器時,自然無法找到之前的會話。但是,如果服務器設置將Cookie保存到硬盤上,又或者通過某些技術手段修改瀏覽器發出的HTTP請求頭,讓瀏覽器再次向服務器發送原來的Cookie,那么再次打開瀏覽器訪問服務器時,依然能夠找到原來的會話ID,進而保持登錄狀態。
????????也正因為關閉瀏覽器不會直接致使會話被刪除,所以服務器需要為會話設置一個失效時間。當客戶端距離上一次使用會話的時間超過這個設定的失效時間,服務器便會判定客戶端已停止活動,從而刪除會話,以此節省存儲空間。
二、代理的基本原理
????????在編寫爬蟲程序時,大家常常會碰到這樣的狀況。剛開始,爬蟲能夠正常運轉,順利抓取數據。但沒過多久,程序可能就會報錯,最常見的就是403 Forbidden錯誤。這時候打開對應的網頁,可能會看到“您的IP訪問頻率太高”的提示。出現這種情況,是因為網站采用了反爬蟲手段。網站服務器會監測某個IP在一定時間內的請求次數,一旦請求次數超過預先設定的閾值,服務器就會直接拒絕服務,返回錯誤信息,這就是我們常說的封IP。
????????既然服務器是依據IP在單位時間內的請求次數來進行檢測的,那只要想辦法偽裝我們的IP地址,讓服務器無法察覺請求來自本地,不就能避免IP被封了嗎?
????????使用代理就是一種行之有效的辦法。后續,我們會詳細講解代理的使用方法。在此之前,我們有必要先了解代理的基本原理,弄清楚它究竟是如何實現IP偽裝的。
2.1 基本原理
????????代理,說的就是代理服務器,英文叫proxy server。它能代替網絡用戶去獲取網絡信息,打個比方,它就像網絡信息的“中轉站”。
????????平常我們訪問網站時,會直接給Web服務器發送請求,Web服務器處理后,把響應結果回傳給我們。要是設置了代理服務器,就如同在我們自己的設備和Web服務器之間架起了一座“橋”。這時候,我們的設備不再直接向Web服務器發起請求,而是將請求發送給代理服務器。代理服務器收到請求后,再把它轉交給Web服務器。Web服務器處理完請求,將響應返回給代理服務器,代理服務器又會把響應轉發給我們的設備。
????????通過這樣的流程,我們依舊可以正常瀏覽網頁。而且,Web服務器識別出的IP是代理服務器的,而非我們本機的IP,就這樣,成功實現了IP偽裝,這便是代理的基本工作原理。
2.2 代理的作用
代理到底有什么用呢?下面簡單給大家說一說:
(1)突破IP訪問限制:有些網站我們平常無法直接訪問,借助代理,就能突破限制,正常訪問這些站點。
(2)訪問內部資源:以教育網為例,使用教育網內地址段的免費代理服務器,就能訪問教育網開放的各類FTP服務,進行資料的下載、上傳,還能查詢和共享各類學習資料。
(3)加快訪問速度:一般來說,代理服務器都會配置一個大容量的硬盤緩沖區。當有信息通過代理服務器時,這些信息會被緩存到緩沖區里。當其他用戶再次訪問相同信息時,代理服務器就可以直接從緩沖區調取信息,快速傳給用戶,大大提高了訪問速度。
(4)隱藏真實IP:通過代理上網,用戶能隱藏自己的真實IP,降低遭受攻擊的風險。對爬蟲來說,使用代理能隱藏爬蟲程序所在的IP,防止因頻繁訪問被網站封鎖IP 。
2.3 爬蟲代理
????????爬蟲爬取數據的速度往往很快,這就導致在爬取時,同一個IP可能會過于頻繁地訪問網站。一旦出現這種情況,網站為了防范,可能會要求我們輸入驗證碼才能繼續訪問,甚至直接封鎖這個IP。這無疑給爬蟲的爬取工作造成很大阻礙。
????????而使用代理就能解決這個問題。通過使用代理,我們可以隱藏爬蟲程序所在設備的真實IP,讓網站服務器以為請求是代理服務器發出的。在爬取過程中,要是我們持續更換不同的代理,網站就難以鎖定并封鎖我們的IP,爬蟲也就可以較為順利地開展爬取工作了 。
2.4 代理分類
代理按照不同標準,可以從協議類型和匿名程度這兩個方面進行分類。
(1)按照協議分類
依據代理所遵循的協議,主要有下面這些類型:
????????- FTP代理服務器:專門用來訪問FTP服務器,一般能實現文件的上傳、下載,還帶有緩存功能。它常用的端口是21、2121 。
????????- HTTP代理服務器:主要用來訪問網頁,多數帶有內容過濾功能,還能緩存網頁數據。常見端口有80、8080、3128。
????????- SSL/TLS代理:如果要訪問加密網站,就會用到它。這類代理一般具備SSL或TLS加密功能,最高支持128位加密強度,常用端口是443。
????????- RTSP代理:主要服務于Real流媒體服務器的訪問,通常帶有緩存功能,端口多為554。
????????- Telnet代理:多用于Telnet遠程控制場景,黑客入侵電腦時,常借助它隱藏自己的身份,端口一般是23。
????????- POP3/SMTP代理:在使用POP3/SMTP方式收發郵件時會用到,通常有緩存郵件數據的功能,使用的端口一般是110和25。
????????- SOCKS代理:它只負責傳遞數據包,不關注具體協議和使用方法,速度相對較快,也帶有緩存功能,端口多為1080。SOCKS代理協議分為SOCKS4和SOCKS5,SOCKS4僅支持TCP協議,而SOCKS5不僅支持TCP,還支持UDP,并且支持多種身份驗證機制和服務器端域名解析。簡單來講,SOCKS4能干的事,SOCKS5都能做,但SOCKS5能做的,SOCKS4不一定能做到。
(2)按照匿名程度分類
根據代理的匿名程度差異,又可以分為以下幾類:
????????- 高度匿名代理:轉發數據包時,不會做任何修改。在服務器端看來,就像是普通客戶端在發起訪問,記錄的IP地址也是代理服務器的。
????????- 普通匿名代理:在轉發數據包時,會對數據包做一些處理。服務器端有可能察覺到這是代理服務器在訪問,甚至有一定概率追蹤到客戶端的真實IP。這類代理服務器一般會添加HTTP_VIA和HTTP_X_FORWARDED_FOR等HTTP頭信息。
????????- 透明代理:不僅會修改數據包,還會直接把客戶端的真實IP告知服務器。這類代理除了能借助緩存技術提升瀏覽速度,利用內容過濾增強安全性外,沒有其他突出作用,常見于內網中的硬件防火墻。
????????- 間諜代理:由組織或個人搭建,目的是記錄用戶傳輸的數據,進而對用戶行為展開研究和監控。
2.5 常見代理設置
下面給大家介紹幾種常見的獲取代理的途徑:
????????(1)使用網上免費代理:優先選擇高匿名代理。網上免費代理數量有限,且質量參差不齊。在使用之前,得篩選出可用的代理。為了更方便地使用,還可以搭建并維護一個代理池。
????????(2)使用付費代理服務:互聯網上有不少提供代理服務的商家,只要支付一定費用,就能使用他們的代理服務。相比免費代理,付費代理的穩定性和可用性都要好很多。
????????(3)ADSL撥號:每次進行ADSL撥號,都會獲取一個新的IP地址。這種方式穩定性高,在解決IP限制問題上,是個比較有效的辦法。
????????后面的內容里,我們會詳細講解這幾種代理的具體使用方法。
參考學習書籍:Python 3網絡爬蟲開發實戰