【爬虫系列】WebSocket握手验证请求 前言 一、Web

前言

查了下最新的反爬虫方式,看到一个WebSocket握手验证反爬虫,还没有遇到过,找了个网站试一试~
最新反爬方式:blog.csdn.net/qq_26079939…


一、WebSocket是什么?

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

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

在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

二、WebSocket握手验证反爬虫

1.目标网站

乐鱼体育:live.611.com/zq

2.网站分析

1.建立Socket链接的地址,其中9394adf88ece4ff08f9ac6e82949f3a1参数是变值

在这里插入图片描述
在这里插入图片描述

2.通过如下方式获取token

1
2
3
4
5
6
7
8
9
python复制代码def getToken():
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("请求错误")

3.从下面的图可以看出,绿色的箭头是客户端发送给服务器的数据,红色箭头是服务器响应的数据

在这里插入图片描述

3.获取数据

Python 库中用于连接 WebSocket 的有很多,但是易用、稳定的有 websocket-client(非异步)、websockets(异步)、aiowebsocket(异步),以下用websocket-client和websockets方式实现。

websocket-client方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
python复制代码import requests
import websocket
import json
import time


def getToken(): # 获取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(): # 需要发送的数据
timestamp = int(time.time()) * 1000
info = {'chrome': 'true', 'version': '80.0.3987.122', 'webkit': 'true'}
message1 = {
"command": "RegisterInfo",
"action": "Web",
"ids": [],
"UserInfo": {
"Version": str([timestamp]) + json.dumps(info),
"Url": "https://live.611.com/zq"
}
}
message2 = {
"command": "JoinGroup",
"action": "SoccerLiveOdd",
"ids": []
}
message3 = {
"command": "JoinGroup",
"action": "SoccerLive",
"ids": []
}
return json.dumps(message1), json.dumps(message2), json.dumps(message3)


def Download(token,message1,message2,message3):
uri = "wss://push.611.com:6119/{}".format(token)
ws = websocket.create_connection(uri, timeout=10)
ws.send(message1)
ws.send(message2)
ws.send(message3)
while True:
result = ws.recv()
print(result)

if __name__ == '__main__':
token = getToken() # 获取token字符串
message1, message2, message3 = get_message() # 构造请求信息
Download(token,message1, message2,message3) # 抓取数据

运行结果在这里插入图片描述

websockets方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
python复制代码import asyncio
import logging
import time,json,requests
from aiowebsocket.converses import AioWebSocket


def getToken():
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(): # 需要发送的数据
timestamp = int(time.time()) * 1000
info = {'chrome': 'true', 'version': '80.0.3987.122', 'webkit': 'true'}
message1 = {
"command": "RegisterInfo",
"action": "Web",
"ids": [],
"UserInfo": {
"Version": str([timestamp]) + json.dumps(info),
"Url": "https://live.611.com/zq"
}
}
message2 = {
"command": "JoinGroup",
"action": "SoccerLiveOdd",
"ids": []
}
message3 = {
"command": "JoinGroup",
"action": "SoccerLive",
"ids": []
}
return message1, message2, message3

async def startup():
token = getToken() # 获取token字符串
uri = "wss://push.611.com:6119/{}".format(token)
message1, message2,message3 = get_message() # 构造请求信息
async with AioWebSocket(uri) as aws:
converse = aws.manipulator
await converse.send(json.dumps(message1))
await converse.send(json.dumps(message2))
await converse.send(json.dumps(message3))
while True:
mes = await converse.receive()
if mes:
msg = json.loads(str(mes, encoding="utf-8"))
print(msg)


if __name__ == '__main__':
try:
asyncio.get_event_loop().run_until_complete(startup())
except KeyboardInterrupt as exc:
logging.info('Quit.')

运行结果

在这里插入图片描述


三、 总结

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

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

服务器端创建 socket 服务后监听客户端,使用 while True 的方式读取客户端发送的消息

然后对服务器端发送的握手请求进验证,如果验证通过,则返回状态码为 101 的响应头,否则返回状态码为 403 的响应头

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%