实时抓取网页数据(web前后端传输场景-异步爬取websocket的库)
优采云 发布时间: 2022-03-03 11:11实时抓取网页数据(web前后端传输场景-异步爬取websocket的库)
在web的前后端传输场景中,有一种请求方式不是http/https协议,而是服务端通过websockets主动向客户端发起数据推送。弹幕、直播、个股等常用数据,实时更新能力比较强。,所以需要更频繁的数据交互,爬取webscoket数据的方式类似。这里有两个异步爬取websockets的库,第一个是websockets
import asyncio
import websockets
from datetime import datetime
async def hello(uri):
async with websockets.connect(uri) as websocket:
while True:
await websocket.send(b'AioWebSocket - Async WebSocket Client')
mes = await websocket.recv()
print('{time}-Client receive: {rec}'
.format(time=datetime.now().strftime('%Y-%m-%d %H:%M:%S'), rec=mes))
asyncio.get_event_loop().run_until_complete(
hello('ws://echo.websocket.org'))
Socket一般与asyncio异步使用,将目标ws或wss地址抛入事件循环。ws 和 wss 的关系类似于 http 和 https 的关系。如何检查,例如
打开这个网站后,在控制台选择ws,
可以看到wss请求是socket的地址。一般来说,101表示请求成功。打开 Frames 以观察客户端和服务器之间的交互。向上的箭头是客户端发给服务器的参数,向下的箭头是服务器。对于返回的数据,一般由客户端为我们进行init操作。我们只需要发送要捕获的目标数据。
除了上面的websockets,还可以使用aiowebsocket,基本用法如下
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.')
异步代码仍然在 asyncio 的事件循环中执行。上面的代码只是抓取,并没有演示向服务器提交数据。下面模仿浏览器的请求
import asyncio
import logging
from datetime import datetime
from aiowebsocket.converses import AioWebSocket
import json
async def startup(uri):
async with AioWebSocket(uri) as aws:
converse = aws.manipulator
# 客户端给服务端发送消息
await converse.send('{"type":"GQL_START","id":"2","query":{"id":"14","variables":{}},"span":{}}')
while True:
mes = await converse.receive()
dict_ = json.loads(mes)
print(dict_)
if __name__ == '__main__':
remote = 'wss://neotracker.io/graphql'
try:
asyncio.get_event_loop().run_until_complete(startup(remote))
except KeyboardInterrupt as exc:
logging.info('Quit.')
运行后会继续向客户端返回数据。由于返回的数据是一个包裹在字符串中的字典,只需用 json.loads 转换即可
然后如果你用mac运行会发现如下错误
SSL handshake failed on verifying the certificate
protocol:
transport:
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1056)
Traceback (most recent call last):
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1056)
大概意思是证书错误,握手失败?这个时候试试关机....我的经验是网上找了各种方法都没用,一气之下重启电脑,然后就好了