• [放鞭炮][福]玉竹斑斑节日快乐![福][放鞭炮] 2019-05-23
  • 三狮军团首秀 只有两千多球迷观战 2019-05-19
  • 人民网2017呼和浩特徒步迎新活动--内蒙古频道--人民网 2019-05-19
  • 【品牌资讯】环球网斩获“全国行业新闻网站传播力2017年6月榜”多项冠军 2019-05-15
  • 深化对经济工作主线的认识 从供需关系看供给侧结构性改革 2019-05-15
  • 格拉斯哥艺术学院起火 4年前曾遭火灾仍在整修 2019-05-14
  • 回复@地瓜干17世:猪临死才会嚎叫呢~ 2019-05-14
  • 婺源古村溪中发现鹰嘴龟 2019-05-08
  • 编辑评测:高夫净源控油平衡露 极速补水长效控油 2019-05-08
  • 四部门发文规范特色小镇建设防止“新瓶装旧酒” 2019-05-02
  • 【地球的盛会文明的聚会艺术的盛宴四海一家足球为人类和平幸福而荣耀!!!普京是当今人类世界最优秀的一代伟人俄罗斯赢啦!!!】 2019-04-29
  • 学习新思想,千万师生同上一堂课 2019-04-28
  • 你这种个体户都干不了的老蚕也配谈计划?真是笑死人不偿命哦? 2019-04-23
  • 感人!的哥带着患病父亲出车 孝心感动乘客 2019-04-23
  • 图解:习近平在纪念马克思诞辰200周年大会上讲话的16个金句 2019-04-16
  • 山西十一选五前三直遗漏:Python如何爬取实时变化的WebSocket数据的方法

    山西体彩11选5直选遗漏 www.caxru.com  更新时间:2019年03月09日 11:26:22   作者:AsyncIns   我要评论

    这篇文章主要介绍了Python如何爬取实时变化的WebSocket数据的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    一、前言

    作为一名爬虫工程师,在工作中常?;嵊龅脚廊∈凳笔莸男枨?,比如体育赛事实时数据、股市实时数据或币圈实时变化的数据。如下图:

    Web 领域中,用于实现数据'实时'更新的手段有轮询和 WebSocket 这两种。轮询指的是客户端按照一定时间间隔(如 1 秒)访问服务端接口,从而达到 '实时' 的效果,虽然看起来数据像是实时更新的,但实际上它有一定的时间间隔,并不是真正的实时更新。轮询通常采用 拉 模式,由客户端主动从服务端拉取数据。

    WebSocket 采用的是 推 模式,由服务端主动将数据推送给客户端,这种方式是真正的实时更新。

    二、什么是 WebSocket

    WebSocket是一种在单个TCP连接上进行全双工通信的协议。它使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

    WebSocket 优点

    • 较少的控制开销:只需要进行一次握手,携带一次请求头信息即可,后续只传输数据即可,相比 HTTP 每次请求都携带请求头,WebSocket 非常省资源。
    • 更强的实时性:由于服务器可以主动推送消息,这使得延迟变得可以忽略不计,相比 HTTP 轮询的时间间隔,WebSocket 可以在相同的时间内进行多次传输。
    • 二进制支持:WebSocket 支持二进制帧,这意味着传输更节省。
    • ……

    爬虫面对 HTTP 和 WebSocket

    Python 中的网络请求库非常多,Requests 是最常用的请求库之一,它可以模拟发送网络请求。但是这些请求都是基于 HTTP 协议的。在面对 WebSocket 的时候 Requests 就发挥不料作用了,必须使用能够连接 WebSocket 的库。

    三、爬取思路

    这里以莱特币官网 //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 中提供的示例代码来测试:

    import asyncio
    import logging
    from datetime import datetime
    from aiowebsocket.converses import AioWebSocket
    
    
    async def startup(uri):
     async with AioWebSocket(uri) as aws:
      converse = aws.manipulator
      message = b'AioWebSocket - Async WebSocket Client'
      while True:
       await converse.send(message)
       print('{time}-Client send: {message}'
         .format(time=datetime.now().strftime('%Y-%m-%d %H:%M:%S'), message=message))
       mes = await converse.receive()
       print('{time}-Client receive: {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))
     except KeyboardInterrupt as exc:
      logging.info('Quit.')

    运行后的结果输出为:

    2019-03-07 15:43:55-Client send: b'AioWebSocket - Async WebSocket Client'
    2019-03-07 15:43:55-Client receive: b'AioWebSocket - Async WebSocket Client'
    2019-03-07 15:43:55-Client send: b'AioWebSocket - Async WebSocket Client'
    2019-03-07 15:43:56-Client receive: b'AioWebSocket - Async WebSocket Client'
    2019-03-07 15:43:56-Client send: b'AioWebSocket - Async WebSocket Client'
    ……

    send 表示客户端向服务端发送的消息

    recive 表示服务端向客户端推送的消息

    五、编码获取数据

    回到这一次的爬取需求,目标网站是莱特币官网:

    从刚才的网络请求记录中,我们得知目标网站的 WebSocket 地址为: wss://api.bbxapp.vip/v1/ifcontract/realTime ,从地址中可以看出目标网站使用的是 wss,也就是 ws 的安全版,它们的关系跟 HTTP/HTTPS 一样。aiowebsocket 会自动处理并识别 ssl,所以我们并不需要作额外的操作,只需要将目标地址赋值给连接 uri 即可:

    import asyncio
    import logging
    from datetime import datetime
    from aiowebsocket.converses import AioWebSocket
    
    
    async def startup(uri):
     async with AioWebSocket(uri) as aws:
      converse = aws.manipulator
      while True:
       mes = await converse.receive()
       print('{time}-Client receive: {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))
     except KeyboardInterrupt as exc:
      logging.info('Quit.')

    运行代码后观察输出,你会发现什么都没有发生。既没有内容输出,也没有断开连接,程序一直在运行,但是什么都没有:

    这是为什么呢?

    是对方不接受我方的请求吗?

    还是有什么反爬虫限制呢?

    实际上,刚才的流程图可以解释这个问题:

    整个流程中有一步是需要客户端给服务端发送指定的消息,服务端验证后才会不停推送数据。所以,应该在消息读取前、握手连接后加上消息发送的代码:

    import asyncio
    import logging
    from datetime import datetime
    from aiowebsocket.converses import AioWebSocket
    
    
    async def startup(uri):
     async with AioWebSocket(uri) as aws:
      converse = aws.manipulator
      # 客户端给服务端发送消息
      await converse.send('{"action":"subscribe","args":["QuoteBin5m:14"]}')
      while True:
       mes = await converse.receive()
       print('{time}-Client receive: {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))
     except KeyboardInterrupt as exc:
      logging.info('Quit.')

    保存后运行,就会看到数据源源不断的推送过来:

    到这里,爬虫就能够获取到想要的数据了。

    aiowebsocket 做了什么

    代码不长,使用的时候只需要将目标网站 WebSocket 地址填入,然后按照流程发送数据即可,那么 aiowebsocket 在这个过程中做了什么呢?

    • 首先,aiowebsocket 根据 WebSocket 地址,向指定的服务端发送握手请求,并校验握手结果。
    • 然后,在确认握手成功后,将数据发送给服务端。
    • 整个过程中为了保持连接不断开,aiowebsocket 会自动与服务端响应 ping pong。
    • 最后,aiowebsocket 读取服务端推送的消息

    【奎因:】如果你认为 aiowebsocket 帮助了你,那么请你到 Github https://github.com/asyncins/aiowebsocket 上给一个 Star。如果在使用当中发现问题或者希望给 aiowebsocket 提建议,那么也可以到 Github 上提出。只要你提出建议,就一定能够帮助 aiowebsocket 变的更好,而 aiowebsocket 也能够继续为你服务。

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    相关文章

    • linux系统使用python获取cpu信息脚本分享

      linux系统使用python获取cpu信息脚本分享

      这篇文章主要介绍了linux系统使用python获取cpu信息脚本,大家参考使用吧
      2014-01-01
    • Python3.4解释器用法简单示例

      Python3.4解释器用法简单示例

      这篇文章主要介绍了Python3.4解释器用法,结合简单实例形式分析了Windows与Linux系统环境中Python3.4解释器的简单使用方法,需要的朋友可以参考下
      2019-03-03
    • python实现二维插值的三维显示

      python实现二维插值的三维显示

      这篇文章主要为大家详细介绍了python实现二维插值的三维显示,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
      2018-12-12
    • Python基于Socket实现的简单聊天程序示例

      Python基于Socket实现的简单聊天程序示例

      这篇文章主要介绍了Python基于Socket实现的简单聊天程序,结合简单实例形式分析了Python聊天程序的客户端与服务器端相关实现技巧,需要的朋友可以参考下
      2017-08-08
    • Python中的条件判断语句基础学习教程

      Python中的条件判断语句基础学习教程

      这篇文章主要介绍了Python中的条件判断语句基础学习教程,文中使用的是Python2.x版本但条件语句部分的使用规则未在3.x中改变,需要的朋友可以参考下
      2016-02-02
    • 简单介绍Python中利用生成器实现的并发编程

      简单介绍Python中利用生成器实现的并发编程

      这篇文章主要介绍了简单介绍Python中利用生成器实现的并发编程,使用yield生成器函数进行多进程编程是Python学习进阶当中的重要知识,需要的朋友可以参考下
      2015-05-05
    • python实现杨辉三角思路

      python实现杨辉三角思路

      本文给大家分享的是作者使用python实现杨辉三角的思路,非常的实用,有需要的小伙伴可以参考下
      2017-07-07
    • python实现神经网络感知器算法

      python实现神经网络感知器算法

      这篇文章主要为大家详细介绍了python实现神经网络感知器算法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
      2017-12-12
    • Python设计模式之命令模式简单示例

      Python设计模式之命令模式简单示例

      这篇文章主要介绍了Python设计模式之命令模式,简单介绍了命令模式的概念、原理,并结合实例形式分析了Python命令模式的定义与使用相关操作技巧,需要的朋友可以参考下
      2018-01-01
    • python回溯法实现数组全排列输出实例分析

      python回溯法实现数组全排列输出实例分析

      这篇文章主要介绍了python回溯法实现数组全排列输出,以实例形式较为详细的分析了全排列的定义及回溯法的实现技巧,需要的朋友可以参考下
      2015-03-03

    最新评论

  • [放鞭炮][福]玉竹斑斑节日快乐![福][放鞭炮] 2019-05-23
  • 三狮军团首秀 只有两千多球迷观战 2019-05-19
  • 人民网2017呼和浩特徒步迎新活动--内蒙古频道--人民网 2019-05-19
  • 【品牌资讯】环球网斩获“全国行业新闻网站传播力2017年6月榜”多项冠军 2019-05-15
  • 深化对经济工作主线的认识 从供需关系看供给侧结构性改革 2019-05-15
  • 格拉斯哥艺术学院起火 4年前曾遭火灾仍在整修 2019-05-14
  • 回复@地瓜干17世:猪临死才会嚎叫呢~ 2019-05-14
  • 婺源古村溪中发现鹰嘴龟 2019-05-08
  • 编辑评测:高夫净源控油平衡露 极速补水长效控油 2019-05-08
  • 四部门发文规范特色小镇建设防止“新瓶装旧酒” 2019-05-02
  • 【地球的盛会文明的聚会艺术的盛宴四海一家足球为人类和平幸福而荣耀!!!普京是当今人类世界最优秀的一代伟人俄罗斯赢啦!!!】 2019-04-29
  • 学习新思想,千万师生同上一堂课 2019-04-28
  • 你这种个体户都干不了的老蚕也配谈计划?真是笑死人不偿命哦? 2019-04-23
  • 感人!的哥带着患病父亲出车 孝心感动乘客 2019-04-23
  • 图解:习近平在纪念马克思诞辰200周年大会上讲话的16个金句 2019-04-16
  • 南国彩票七星彩论坛808 北京赛车规律如何抓 幸福之门幸福彩票走势图 云南时时彩qq群 北京赛车路数分析 排列五历史开奖号码 长沙市有没有中双色球大奖的 山东莱芜福利彩票中心好进吗 中国体育彩票开奖 七乐彩开奖公告 腾讯分分彩按什么开奖 澳洲幸运8计划软件 香港现场开奖报码 北京pk10 9.99平台 14场胜负彩对阵表新浪 qq分分彩计划人工在线