<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Python如何爬取實時變化的WebSocket數據

電子工程師 ? 來源:lp ? 2019-03-11 09:31 ? 次閱讀

一、前言

作為一名爬蟲工程師,在工作中常常會遇到爬取實時數據的需求,比如體育賽事實時數據、股市實時數據或幣圈實時變化的數據。如下圖:

Web 領域中,用于實現數據'實時'更新的手段有輪詢和 WebSocket 這兩種。輪詢指的是客戶端按照一定時間間隔(如 1 秒)訪問服務端接口,從而達到 '實時' 的效果,雖然看起來數據像是實時更新的,但實際上它有一定的時間間隔,并不是真正的實時更新。輪詢通常采用 拉 模式,由客戶端主動從服務端拉取數據。

WebSocket 采用的是 推 模式,由服務端主動將數據推送給客戶端,這種方式是真正的實時更新。

二、什么是 WebSocket

WebSocket是一種在單個TCP連接上進行全雙工通信的協議。它使得客戶端和服務器之間的數據交換變得更加簡單,允許服務端主動向客戶端推送數據。在WebSocket API中,瀏覽器和服務器只需要完成一次握手,兩者之間就直接可以創建持久性的連接,并進行雙向數據傳輸。

WebSocket 優點

較少的控制開銷:只需要進行一次握手,攜帶一次請求頭信息即可,后續只傳輸數據即可,相比 HTTP 每次請求都攜帶請求頭,WebSocket 非常省資源。

更強的實時性:由于服務器可以主動推送消息,這使得延遲變得可以忽略不計,相比 HTTP 輪詢的時間間隔,WebSocket 可以在相同的時間內進行多次傳輸。

二進制支持:WebSocket 支持二進制幀,這意味著傳輸更節省。

……

爬蟲面對 HTTP 和 WebSocket

Python 中的網絡請求庫非常多,Requests 是最常用的請求庫之一,它可以模擬發送網絡請求。但是這些請求都是基于 HTTP 協議的。在面對 WebSocket 的時候 Requests 就發揮不料作用了,必須使用能夠連接 WebSocket 的庫。

三、爬取思路

這里以萊特幣官網 http://www.laiteb.com/ 實時數據為例。WebSocket 的握手只發生一次,所以如果需要通過瀏覽器開發者工具觀察網絡請求,則需要在打開頁面的情況下,打開瀏覽器開發者工具,定位到 NewWork 選項卡,并輸入或刷新當前頁面,才能觀察到 WebSocket 的握手請求和數據傳輸情況。這里以 Chrome 瀏覽器為例:

在開發者工具中提供了篩選功能,其中 WS 選項代表只顯示 WebSocket 連接的網絡請求。

這時候可以看到請求記錄列表中有一條名為 realTime 的記錄,鼠標左鍵點擊它后,開發者工具會分為左右兩欄,右側列出本條請求記錄的詳細信息:

與 HTTP 請求不同的是,WebSocket 連接地址以 ws 或 wss 開頭。連接成功的狀態碼不是 200,而是 101。

Headers 標簽頁記錄的是 Request 和 Response 信息,而 Frames 標簽頁中記錄的則是雙方互傳的數據,也是我們需要爬取的數據內容:

Frames 圖中綠色箭頭向上的數據是客戶端發送給服務端的數據,橙色箭頭向下的數據是服務端推送給客戶端的數據。

從數據順序中可以看到,客戶端先發送:

{"action":"subscribe","args":["QuoteBin5m:14"]}

然后服務端才會推送信息(一直推送):

{"group":"QuoteBin5m:14","data":[{"low":"55.42","high":"55.63","open":"55.42","close":"55.59","last_price":"55.59","avg_price":"55.5111587372932781077","volume":"40078","timestamp":1551941701,"rise_fall_rate":"0.0030674846625766871","rise_fall_value":"0.17","base_coin_volume":"400.78","quote_coin_volume":"22247.7621987324"}]}

所以,從發起握手到獲得數據的整個流程為:

那么,現在問題來了:

握手怎么弄?

連接保持怎么弄?

消息發送和接收怎么弄?

有什么庫可以輕松實現嗎?

四、aiowebsocket

Python 庫中用于連接 WebSocket 的有很多,但是易用、穩定的有 websocket-client(非異步)、websockets(異步)、aiowebsocket(異步)。

可以根據項目需求選擇三者之一,今天介紹的是異步 WebSocket 連接客戶端 aiowebsocket。

Github 地址為:https://github.com/asyncins/aiowebsocket

ReadMe中介紹到:

AioWebSocket是一個遵循 WebSocket 規范的 異步 WebSocket 客戶端,相對于其他庫它更輕、更快。

它的安裝和其他庫一樣簡單,使用pip install aiowebsocket即可。安裝好后,我們可以根據 ReadMe 中提供的示例代碼來測試:

importasyncioimportloggingfromdatetimeimportdatetimefromaiowebsocket.conversesimportAioWebSocketasyncdefstartup(uri):asyncwithAioWebSocket(uri)asaws:converse=aws.manipulatormessage=b'AioWebSocket-AsyncWebSocketClient'whileTrue:awaitconverse.send(message)print('{time}-Clientsend:{message}'.format(time=datetime.now().strftime('%Y-%m-%d%H:%M:%S'),message=message))mes=awaitconverse.receive()print('{time}-Clientreceive:{rec}'.format(time=datetime.now().strftime('%Y-%m-%d%H:%M:%S'),rec=mes))if__name__=='__main__':remote='ws://echo.websocket.org'try:asyncio.get_event_loop().run_until_complete(startup(remote))exceptKeyboardInterruptasexc:logging.info('Quit.')

運行后的結果輸出為:

2019-03-0715:43:55-Clientsend:b'AioWebSocket-AsyncWebSocketClient'2019-03-0715:43:55-Clientreceive:b'AioWebSocket-AsyncWebSocketClient'2019-03-0715:43:55-Clientsend:b'AioWebSocket-AsyncWebSocketClient'2019-03-0715:43:56-Clientreceive:b'AioWebSocket-AsyncWebSocketClient'2019-03-0715:43:56-Clientsend:b'AioWebSocket-AsyncWebSocketClient'……

send 表示客戶端向服務端發送的消息

recive 表示服務端向客戶端推送的消息

五、編碼獲取數據

回到這一次的爬取需求,目標網站是萊特幣官網:

從剛才的網絡請求記錄中,我們得知目標網站的 WebSocket 地址為:wss://api.bbxapp.vip/v1/ifcontract/realTime,從地址中可以看出目標網站使用的是 wss,也就是 ws 的安全版,它們的關系跟 HTTP/HTTPS 一樣。aiowebsocket 會自動處理并識別 ssl,所以我們并不需要作額外的操作,只需要將目標地址賦值給連接 uri 即可:

importasyncioimportloggingfromdatetimeimportdatetimefromaiowebsocket.conversesimportAioWebSocketasyncdefstartup(uri):asyncwithAioWebSocket(uri)asaws:converse=aws.manipulatorwhileTrue:mes=awaitconverse.receive()print('{time}-Clientreceive:{rec}'.format(time=datetime.now().strftime('%Y-%m-%d%H:%M:%S'),rec=mes))if__name__=='__main__':remote='wss://api.bbxapp.vip/v1/ifcontract/realTime'try:asyncio.get_event_loop().run_until_complete(startup(remote))exceptKeyboardInterruptasexc:logging.info('Quit.')

運行代碼后觀察輸出,你會發現什么都沒有發生。既沒有內容輸出,也沒有斷開連接,程序一直在運行,但是什么都沒有:

這是為什么呢?

是對方不接受我方的請求嗎?

還是有什么反爬蟲限制呢?

實際上,剛才的流程圖可以解釋這個問題:

整個流程中有一步是需要客戶端給服務端發送指定的消息,服務端驗證后才會不停推送數據。所以,應該在消息讀取前、握手連接后加上消息發送的代碼:

importasyncioimportloggingfromdatetimeimportdatetimefromaiowebsocket.conversesimportAioWebSocketasyncdefstartup(uri):asyncwithAioWebSocket(uri)asaws:converse=aws.manipulatorwhileTrue:mes=awaitconverse.receive()print('{time}-Clientreceive:{rec}'.format(time=datetime.now().strftime('%Y-%m-%d%H:%M:%S'),rec=mes))if__name__=='__main__':remote='wss://api.bbxapp.vip/v1/ifcontract/realTime'try:asyncio.get_event_loop().run_until_complete(startup(remote))exceptKeyboardInterruptasexc:logging.info('Quit.')

保存后運行,就會看到數據源源不斷的推送過來:

到這里,爬蟲就能夠獲取到想要的數據了。

aiowebsocket 做了什么

代碼不長,使用的時候只需要將目標網站 WebSocket 地址填入,然后按照流程發送數據即可,那么 aiowebsocket 在這個過程中做了什么呢?

首先,aiowebsocket 根據 WebSocket 地址,向指定的服務端發送握手請求,并校驗握手結果。

然后,在確認握手成功后,將數據發送給服務端。

整個過程中為了保持連接不斷開,aiowebsocket 會自動與服務端響應 ping pong。

最后,aiowebsocket 讀取服務端推送的消息

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Web
    Web
    +關注

    關注

    2

    文章

    1238

    瀏覽量

    68482
  • python
    +關注

    關注

    51

    文章

    4678

    瀏覽量

    83477
  • WebSocket
    +關注

    關注

    0

    文章

    24

    瀏覽量

    3657

原文標題:Python如何爬取實時變化的WebSocket數據

文章出處:【微信號:rgznai100,微信公眾號:rgznai100】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    python實現網頁爬蟲圖片

    來實現這樣一個簡單的爬蟲功能,把我們想要的代碼取到本地,功能有點類似我們之前學過的批處理。下面就看看如何使用python來實現這樣一個功能,主要分為三步,如下:一. 獲取整個頁面數據首先我們可以先
    發表于 04-05 15:32

    Python爬蟲與Web開發庫盤點

    Python爬蟲和Web開發均是與網頁相關的知識技能,無論是自己搭建的網站還是爬蟲去別人的網站,都離不開相應的Python庫,以下是常用的Python爬蟲與Web開發庫。1.爬蟲庫
    發表于 05-10 15:21

    python

    python學習1.數據2.圖片
    發表于 09-21 18:18

    采用xpath網站內容

    xpathmooc網課程
    發表于 04-11 12:01

    基于Python3對攜程網頁上北京五星級酒店列表的

    Python3 攜程網[1] 根據好評優先順序,獲取北京五星級酒店列表
    發表于 04-19 16:25

    基于Python實現一只小爬蟲拉勾網職位信息的方法

    通俗易懂的分析如何用Python實現一只小爬蟲,拉勾網的職位信息
    發表于 05-17 06:54

    python音頻文件的步驟

    python爬蟲音頻文件
    發表于 08-22 14:23

    Python豆瓣電影信息和存儲數據

    Python——豆瓣電影信息并存儲數據
    發表于 03-11 11:19

    0基礎入門Python爬蟲實戰課

    ,爬蟲功不可沒。通過爬蟲,可以從知乎、微博熱門話題,篩選優質答案,分析用戶偏好;從淘寶、京東商品、評論及銷量數據,分析用戶消費場景;
    發表于 07-25 09:28

    python基礎語法及流程控制

    爬蟲復習1.python基礎python基礎語法 流程控制 函數封裝2.防措施整體防User-AgentrefererIP代理池Cookie代理池 各自防
    發表于 08-31 07:41

    Python爬蟲簡介與軟件配置

    Python爬蟲練習一、爬蟲簡介1. 介紹2. 軟件配置二、南陽理工OJ題目三、學校信息通知四、總結五、參考一、爬蟲簡介1. 介紹網
    發表于 01-11 06:32

    豆瓣電影Top250信息

    ) # 判斷是否取到數據,并調用解析函數 if html:for item in parsePage(html):writeFile(item)# 判斷當前執行是否為主程序運行,并遍歷調用主函數
    發表于 03-23 15:47

    【廣東龍芯2K500先鋒板試用體驗】3.開發http服務與通過websocket實時更新頁面數據

    內容替換。10. 添加websocket服務因為在頁面上需要實時的跟后臺數據,而高效又延時短的通訊方式屬于websocket了。這里只需要
    發表于 01-16 00:33

    WebSocket有什么優點

    WebSocket是一種在單個TCP連接上進行全雙工通信的協議。WebSocket通信協議于2011年被IETF定為標準RFC 6455,并由RFC7936補充規范。WebSocket API也被W3C定為標準。HTML5開始提
    的頭像 發表于 02-15 15:53 ?7978次閱讀
    <b class='flag-5'>WebSocket</b>有什么優點

    websocket協議的原理

    2、WebSocket使得客戶端和服務器之間的數據交換變得更加簡單,允許服務端主動向客戶端推送數據 3、在WebSocket API中,瀏覽器和服務器只需要完成一次握手,兩者之間就
    的頭像 發表于 11-09 15:13 ?434次閱讀
    <b class='flag-5'>websocket</b>協議的原理
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>