WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。,被广泛应用于对数据实时性要求较高的场景,如体育赛事播报、股票走势分析、在线聊天等。
在WebSocket协议未出现之前,很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯
与HTTP协议不同的是,WebSocket协议只需要发送一次连接请求。请求的完整过程被称为握手,即客户端为了创建WebSocket连接而向服务器发送特定的HTTp请求并声明升级协议。WebSocket 是独立的、创建在 TCP 上的协议,通过HTTP/1.1 协议的101状态码进行握手,握手成功后才会转为WebSocket协议。
WebSocket通信过程:
本次抓取的目标网站是乐鱼体育的足球比分页,该页面会实时展示比分更新数据。
请注意:
引入的websocket模块并不是需要下载安装websocket模块(pip install websocket)。而是需要下载安装websocket-client模块。如果你下载了websocket,请卸载!!!
import requests
import websocket
import json
import time
import math
def getToken():
"""
获取加密字符串,将其拼接到websocket协议的url上
:return: token
"""
url = "https://live.611.com/Live/GetToken"
response = requests.get(url)
if response.status_code == 200:
data = json.loads(response.text)
token = data["Data"]
return token
else:
print("请求错误")
def get_message():
"""
构造websocket的验证信息
:return: message1,message2
"""
_time = math.floor(time.time()) * 1000
info = {'chrome': 'true', 'version': '80.0.3987.122', 'webkit': 'true'}
message1 = {
"command": "RegisterInfo",
"action": "Web",
"ids": [],
"UserInfo": {
"Version": str([_time]) + json.dumps(info),
"Url": "https://live.611.com/zq"
}
}
message2 = {
"command": "JoinGroup",
"action": "SoccerLiveOdd",
"ids": []
}
return json.dumps(message1), json.dumps(message2)
def Download(token,message1,message2):
"""
抓取数据
:param token: token
:param message1: message1
:param message2: message2
:return:
"""
uri = "wss://push.611.com:6119/{}".format(token)
ws = websocket.create_connection(uri, timeout=10)
ws.send(message1)
ws.send(message2)
while True:
result = ws.recv()
print(result)
if __name__ == '__main__':
token = getToken() # 获取token字符串
message1, message2 = get_message() # 构造请求信息
Download(token,message1, message2) # 抓取数据
参考资料:菜鸟教程
思路来源:《Python3 反爬虫原理与绕过实战》---- 韦世东 著