精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Python如何爬取實(shí)時(shí)變化的WebSocket數(shù)據(jù)

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

一、前言

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

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

WebSocket 采用的是 推 模式,由服務(wù)端主動(dòng)將數(shù)據(jù)推送給客戶端,這種方式是真正的實(shí)時(shí)更新。

二、什么是 WebSocket

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

WebSocket 優(yōu)點(diǎn)

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

更強(qiáng)的實(shí)時(shí)性:由于服務(wù)器可以主動(dòng)推送消息,這使得延遲變得可以忽略不計(jì),相比 HTTP 輪詢的時(shí)間間隔,WebSocket 可以在相同的時(shí)間內(nèi)進(jìn)行多次傳輸。

二進(jìn)制支持:WebSocket 支持二進(jìn)制幀,這意味著傳輸更節(jié)省。

……

爬蟲面對 HTTP 和 WebSocket

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

三、爬取思路

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

在開發(fā)者工具中提供了篩選功能,其中 WS 選項(xiàng)代表只顯示 WebSocket 連接的網(wǎng)絡(luò)請求。

這時(shí)候可以看到請求記錄列表中有一條名為 realTime 的記錄,鼠標(biāo)左鍵點(diǎn)擊它后,開發(fā)者工具會(huì)分為左右兩欄,右側(cè)列出本條請求記錄的詳細(xì)信息:

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

Headers 標(biāo)簽頁記錄的是 Request 和 Response 信息,而 Frames 標(biāo)簽頁中記錄的則是雙方互傳的數(shù)據(jù),也是我們需要爬取的數(shù)據(jù)內(nèi)容:

Frames 圖中綠色箭頭向上的數(shù)據(jù)是客戶端發(fā)送給服務(wù)端的數(shù)據(jù),橙色箭頭向下的數(shù)據(jù)是服務(wù)端推送給客戶端的數(shù)據(jù)。

從數(shù)據(jù)順序中可以看到,客戶端先發(fā)送:

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

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

{"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"}]}

所以,從發(fā)起握手到獲得數(shù)據(jù)的整個(gè)流程為:

那么,現(xiàn)在問題來了:

握手怎么弄?

連接保持怎么弄?

消息發(fā)送和接收怎么弄?

有什么庫可以輕松實(shí)現(xiàn)嗎?

四、aiowebsocket

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

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

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

ReadMe中介紹到:

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

它的安裝和其他庫一樣簡單,使用pip install aiowebsocket即可。安裝好后,我們可以根據(jù) 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.')

運(yùn)行后的結(jié)果輸出為:

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 表示客戶端向服務(wù)端發(fā)送的消息

recive 表示服務(wù)端向客戶端推送的消息

五、編碼獲取數(shù)據(jù)

回到這一次的爬取需求,目標(biāo)網(wǎng)站是萊特幣官網(wǎng):

從剛才的網(wǎng)絡(luò)請求記錄中,我們得知目標(biāo)網(wǎng)站的 WebSocket 地址為:wss://api.bbxapp.vip/v1/ifcontract/realTime,從地址中可以看出目標(biāo)網(wǎng)站使用的是 wss,也就是 ws 的安全版,它們的關(guān)系跟 HTTP/HTTPS 一樣。aiowebsocket 會(huì)自動(dòng)處理并識(shí)別 ssl,所以我們并不需要作額外的操作,只需要將目標(biāo)地址賦值給連接 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.')

運(yùn)行代碼后觀察輸出,你會(huì)發(fā)現(xiàn)什么都沒有發(fā)生。既沒有內(nèi)容輸出,也沒有斷開連接,程序一直在運(yùn)行,但是什么都沒有:

這是為什么呢?

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

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

實(shí)際上,剛才的流程圖可以解釋這個(gè)問題:

整個(gè)流程中有一步是需要客戶端給服務(wù)端發(fā)送指定的消息,服務(wù)端驗(yàn)證后才會(huì)不停推送數(shù)據(jù)。所以,應(yīng)該在消息讀取前、握手連接后加上消息發(fā)送的代碼:

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.')

保存后運(yùn)行,就會(huì)看到數(shù)據(jù)源源不斷的推送過來:

到這里,爬蟲就能夠獲取到想要的數(shù)據(jù)了。

aiowebsocket 做了什么

代碼不長,使用的時(shí)候只需要將目標(biāo)網(wǎng)站 WebSocket 地址填入,然后按照流程發(fā)送數(shù)據(jù)即可,那么 aiowebsocket 在這個(gè)過程中做了什么呢?

首先,aiowebsocket 根據(jù) WebSocket 地址,向指定的服務(wù)端發(fā)送握手請求,并校驗(yàn)握手結(jié)果。

然后,在確認(rèn)握手成功后,將數(shù)據(jù)發(fā)送給服務(wù)端。

整個(gè)過程中為了保持連接不斷開,aiowebsocket 會(huì)自動(dòng)與服務(wù)端響應(yīng) ping pong。

最后,aiowebsocket 讀取服務(wù)端推送的消息

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • Web
    Web
    +關(guān)注

    關(guān)注

    2

    文章

    1255

    瀏覽量

    69332
  • python
    +關(guān)注

    關(guān)注

    56

    文章

    4782

    瀏覽量

    84449
  • WebSocket
    +關(guān)注

    關(guān)注

    0

    文章

    29

    瀏覽量

    3737

原文標(biāo)題:Python如何爬取實(shí)時(shí)變化的WebSocket數(shù)據(jù)

文章出處:【微信號(hào):rgznai100,微信公眾號(hào):rgznai100】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    python實(shí)現(xiàn)網(wǎng)頁爬蟲圖片

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

    Python爬蟲與Web開發(fā)庫盤點(diǎn)

    Python爬蟲和Web開發(fā)均是與網(wǎng)頁相關(guān)的知識(shí)技能,無論是自己搭建的網(wǎng)站還是爬蟲去別人的網(wǎng)站,都離不開相應(yīng)的Python庫,以下是常用的Python爬蟲與Web開發(fā)庫。1.爬蟲庫
    發(fā)表于 05-10 15:21

    python

    python學(xué)習(xí)1.數(shù)據(jù)2.圖片
    發(fā)表于 09-21 18:18

    采用xpath網(wǎng)站內(nèi)容

    xpathmooc網(wǎng)課程
    發(fā)表于 04-11 12:01

    基于Python3對攜程網(wǎng)頁上北京五星級(jí)酒店列表的

    Python3 攜程網(wǎng)[1] 根據(jù)好評(píng)優(yōu)先順序,獲取北京五星級(jí)酒店列表
    發(fā)表于 04-19 16:25

    基于Python實(shí)現(xiàn)一只小爬蟲拉勾網(wǎng)職位信息的方法

    通俗易懂的分析如何用Python實(shí)現(xiàn)一只小爬蟲,拉勾網(wǎng)的職位信息
    發(fā)表于 05-17 06:54

    python音頻文件的步驟

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

    Python豆瓣電影信息和存儲(chǔ)數(shù)據(jù)

    Python——豆瓣電影信息并存儲(chǔ)數(shù)據(jù)
    發(fā)表于 03-11 11:19

    0基礎(chǔ)入門Python爬蟲實(shí)戰(zhàn)課

    ,爬蟲功不可沒。通過爬蟲,可以從知乎、微博熱門話題,篩選優(yōu)質(zhì)答案,分析用戶偏好;從淘寶、京東商品、評(píng)論及銷量數(shù)據(jù),分析用戶消費(fèi)場景;
    發(fā)表于 07-25 09:28

    python基礎(chǔ)語法及流程控制

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

    豆瓣電影Top250信息

    ) # 判斷是否取到數(shù)據(jù),并調(diào)用解析函數(shù) if html:for item in parsePage(html):writeFile(item)# 判斷當(dāng)前執(zhí)行是否為主程序運(yùn)行,并遍歷調(diào)用主函數(shù)
    發(fā)表于 03-23 15:47

    Python CSDN的極客頭條

    Python 如何CSDN的極客頭條呢?
    的頭像 發(fā)表于 03-21 14:58 ?4798次閱讀
    <b class='flag-5'>Python</b> <b class='flag-5'>爬</b><b class='flag-5'>取</b>CSDN的極客頭條

    如何使用Scrapy網(wǎng)站數(shù)據(jù)

    網(wǎng)頁抓取的主要目標(biāo)是從無結(jié)構(gòu)的來源提取出結(jié)構(gòu)信息。Scrapy爬蟲以Python字典的形式返回提取數(shù)據(jù)。盡管Python字典既方便又熟悉,但仍然不夠結(jié)構(gòu)化:字段名容易出現(xiàn)拼寫錯(cuò)誤,返回不一致的信息,特別是在有多個(gè)爬蟲的大型項(xiàng)目中
    的頭像 發(fā)表于 07-26 09:06 ?5137次閱讀

    如何用python抖音app數(shù)據(jù)

    記錄一下如何用pythonapp數(shù)據(jù),本文以抖音視頻app為例。
    的頭像 發(fā)表于 03-16 09:07 ?5261次閱讀

    Scrapy怎么Python文件

    我們介紹了Scrapy框架運(yùn)行基本原理,緊接著我們介紹了如何利用Scrapy文本數(shù)據(jù)
    的頭像 發(fā)表于 02-24 15:16 ?557次閱讀
    Scrapy怎么<b class='flag-5'>爬</b><b class='flag-5'>取</b><b class='flag-5'>Python</b>文件