python测试websocket接口(Python如何爬取实时变化的WebSocket数据的方法)
python测试websocket接口
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 的库。
三、爬取思路
这里以莱特币官网 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" ]} |
然后服务端才会推送信息(一直推送):
所以,从发起握手到获得数据的整个流程为:
那么,现在问题来了:
- 握手怎么弄?
- 连接保持怎么弄?
- 消息发送和接收怎么弄?
- 有什么库可以轻松实现吗?
四、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 也能够继续为你服务。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持开心学习网。
原文链接:https://juejin.im/post/5c80b768f265da2dae514d4f
- kmp算法怎么用c描述(详解小白之KMP算法及python实现)
- python列表反转的方法(Python实现的列表排序、反转操作示例)
- python最简单实例(Python文件打开方式实例详解a、a+、r+、w+区别)
- python 微信发天气信息(python微信聊天机器人改进版定时或触发抓取天气预报、励志语录等,向好友推送)
- python如何编写一个用户登录系统(Python实现的登录验证系统完整案例基于搭建的MVC框架)
- 如何去阿里云解析域名(利用Python+阿里云实现DDNS动态域名解析的方法)
- python如何把字符串转换成数字(python实现字符串加密成纯数字)
- python爬取豆瓣电影评论(python使用requests模块实现爬取电影天堂最新电影信息)
- python爬虫入门自学(自学python爬虫的建议和周期预算)
- python函数调用传递数组数据(python调用c++传递数组的实例)
- mongodb python教程(python使用pymongo操作mongo的完整步骤)
- python eval函数原理(浅谈Python中eval的强大与危害)
- pythonmatplotlib怎么设置图像(完美解决Python matplotlib绘图时汉字显示不正常的问题)
- python正则表达式处理教学(使用Python正则表达式操作文本数据的方法)
- 怎么用python分析足球(使用Python进行体育竞技分析预测球队成绩)
- python条形码识别(python3转换code128条形码的方法)
- 点赞 禹州苌庄正式撤乡建镇 未来发展不可估量(禹州苌庄正式撤乡建镇)
- 它荣获 中国生态魅力镇 称号 就在咱们禹州,一起来看看(中国生态魅力镇)
- 真牛 禹州将建成中等城市(禹州将建成中等城市)
- 被骂欺师灭祖,与郭德纲公开叫板,何云伟改名何沄伟,开始画画了(与郭德纲公开叫板)
- 相声转行影帝,被何晴抛弃,甩10年女友闪婚生子,刘威不靠谱情史(相声转行影帝被何晴抛弃)
- 岳云鹏不说相声,改行演员了 网友 快回来说相声(岳云鹏不说相声)
热门推荐
- frameset与iframe 的应用与区别
- ubuntu安装hadoop单机版(VMware + Ubuntu18.04 搭建Hadoop集群环境的图文教程)
- vue项目引入element页面(vue-element-admin项目导入和导出的实现)
- php秒杀实现代码(php无限极分类实现方法分析)
- C#中BeginInvoke与EndInvoke
- python下载后依然打不开文件(解决python打不开文件文件不存在的问题)
- SqlTransaction事务的用法
- js宏任务都有哪些(JavaScript 操作宏任务与微任务)
- html5底部组件(HTML5 Blob对象的具体使用)
- laravel指定管理员(在laravel-admin中列表中禁止某行编辑、删除的方法)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9