WebSocket 側重點在Socket。在客戶端與服務器之間交換數據,當兩者連接成功時,就可以保持長期連接,服務器可以直接向客戶端推送數據,無需通過客戶端發送多次請求。
對於某些網站,服務器需要給客戶端(瀏覽器)不斷更新信息,對於這些實時更新的信息(如:服務器每1秒推送一次),大多以WebSocket技術爲主。
在請求網站時,當網頁一加載,在請求中,可以發現狀態爲101,Type 爲 websocket 的響應中,在其Messages中,首先看到客戶端改善1條或n條信息給服務器,之後服務器就給客戶端不停的推送信息,在此期間,客戶端也會在一段時間(如:3秒)內給服務器發送信息,用來確認客戶端還在再服務器連接,如下圖。
而每次服務器推送回來的數據正是我們想要的信息。此時不得不去探究。
WebSocket 特點:
- URL地址以 ws 或 wss 開頭;
- 數據在Messages中不停的推送與驗證;
- 請求/響應頭信息:
- 請求頭:
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: hsbccunVBv4NEdroi/OWcw==
Sec-WebSocket-Version: 13
- 響應頭:
Connection: upgrade
Upgrade: WebSocket
Date: Sun, 15 Mar 2020 13:57:23 GMT
Sec-WebSocket-Accept: ELbu6ydVcJK2fT0RwiV1TvYTJ7g=
++相比平常的請求/響應頭信息,它們多出以上信息。++
Connection: Upgrade
Upgrade: websocket
聲明這是一個websoket協議。
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: hsbccunVBv4NEdroi/OWcw==
Sec-WebSocket-Version: 13
Sec-WebSocket-Accept: ELbu6ydVcJK2fT0RwiV1TvYTJ7g=
用來驗證客戶端與服務器之間的驗證。
WebSocket 簡單說明:
- 服務器:
在服務器中,服務器創建socket服務,使服務器監聽客戶端發送的請求,當客戶端給服務器發送請求(握手請求)後,服務器將請求的信息進行驗證,如果驗證成功,返回101,並與客戶端建立連接,這時客戶端與服務器之間就可以互相通信,否則其它操作(403)。 - 客戶端:
在客戶端中,客戶端按照WebSocket規範生成請求信息(握手信息),並向服務器發送請求,然後對服務器讀取服務器響應信息,最後驗證客戶端與服務器的握手結果。
爬蟲採集(Python):
對於此類,爬蟲如何去採集數據呢?代碼中難點無非是怎樣保持連接、消息發送與連接。
在Python中,我們常使用的urllib、requests等庫已經無法滿足要求。但是對強大Python中,怎麼可能沒有解決的呢。
Python中連接 WebSocket的庫有很多,但是易用、穩定的有 websocket-client(非異步)、websockets(異步)、aiowebsocket(異步)。這裏推薦使用aiowebsocket。Github
WebSocket 爭對爬蟲:
相比平常的網站,Socket技術在爬蟲上面已經是一個坎。但是這個坎不是太深,要想挖更深的坎,需要與JavaScript或其它技術的結合。讓爬蟲工程師覺得成本>信息。
- 挖深坑方式:
1. 添加請求時信息驗證難度。
如:在URl中添加加密信息,在請求中添加加密信息
2. 在握手成功之後添加信息驗證。
如:連接成功之後,需要客戶端發送給服務加密信息驗證
3. 連接成功後,連接中期間不時添加信息客戶端消息驗證。
如:連接成功之後,服務器可以向客戶端正常發送信息,但是需要客戶端每隔斷時間給服務器發送信息。
WebSocket Ping
WebSocket 的保持長時間有憂點也有缺點,就是在長時間連接上,耗費的資源比較大,爲了解決這個問題,所以WebSocket Ping產生了。
WebSocket 協議規範約定,服務器可以向客戶端發送Ping幀,當客戶端收到Ping時應當回覆Pong幀。如果客戶端不回覆或者回復的並不是Pong幀,那麼服務器就可以認爲客戶端異常,主動關閉連接。WebSocket Ping以接收/回覆的方式,使其在工作性能上優於WebSocket。