Python爬虫:Python+WebSocket获取体育实时赛事数据

Python爬虫:Python+WebSocket获取体育实时赛事数据

苦于websocket的能跑的案例太少了,还没开始就要什么逆向,一来就是拦路虎,太折磨人了,无意间看了一个类似的文章并学习更新了,感谢大佬,对websocket有了一个新的认识。
python版本:在这里插入图片描述

目标网站:http://m.611.com/

1、打开开发者工具(Ctrl+Shift+I)启用浏览器仿真器
在这里插入图片描述
2、触摸启用仿真

将鼠标移到设备上可查看圆形“触摸”光标。这将对基于触摸的 JavaScript 事件( 如touchstart,touchmove和touchend)做出反应。鼠标特定的事件和 CSS 效果不会 做出反应。
按住Shift键,然后单击并移动鼠标以模拟双指缩放操作。
通过观察数据一段时间会变~
在这里插入图片描述
没发现比分是怎么和球队怎么拼接而成,疑惑~
通过查看发现是基于websockt实时更新数据,接下来开始分析:
Python爬虫:Python+WebSocket获取体育实时赛事数据_第1张图片
3、参数分析:
{“command”:“RegisterInfo”,“action”:“Web”,“ids”:[],“UserInfo”:{“Version”:“[1667099935000]{“webkit”:true,“version”:“605.1.15”,“safari”:true}”,“Url”:“http://m.611.com/”}}
{“command”:“JoinGroup”,“action”:“SoccerLive”,“ids”:[303794138,303747120,303794153,303748872,303747117,303749323,303755706,303747122,303755264,303794150,303794144,303747115]}
{“command”:“JoinGroup”,“action”:“BasketSoccerLive”,“ids”:[303683091,303683092,303674542,303674543,303674544,303674545,303674546,303683093,303683094,303683096,303683097,303683098]}
通过多次刷新页面/更换浏览器得出结论:
第一条内容是连接服务器用的,action、ids、Url都是不变的,只有UserInfo里面内容是变化的,其中Version中括号里面是一个时间戳+000,后面加浏览器参数,那么只需要更改时间戳就可以了,浏览器参数直接复制就行。
第二、三条内容是加入群组用的,参数都是固定的,不需要改。

4、分析完发送的内容,后面就容易了,只需要再得到url就可以尝试连接了,返回headers界面,发现url后面加了一段字符串参数,字符串每次刷新后都不同,应该是js加密生成的,找js文件逆向太麻烦,先看看前面的请求有没有这个参数;
Python爬虫:Python+WebSocket获取体育实时赛事数据_第2张图片
直接复制f3fa2472b9db40f89bcf82c32e2357e6
ctrl+f搜索:
Python爬虫:Python+WebSocket获取体育实时赛事数据_第3张图片Python爬虫:Python+WebSocket获取体育实时赛事数据_第4张图片
发现这样GET不就可以了,太喜欢这样了,对刚开始学爬虫的小白我才能学的起走……

pip install websocket-client
开始写代码:

import requests

def get_token():
    # 获取token
    token_url = 'http://m.611.com/Live/GetToken'
    headers = {
        'Accept': '*/*',
        'Accept-Language': 'zh-CN,zh;q=0.9',
        'Connection': 'keep-alive',
        'Referer': 'http://m.611.com/',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',
        'X-Requested-With': 'XMLHttpRequest'
    }
    return requests.get(token_url, headers=headers, verify=False).json()['Data']

接着定义一个类,初始化url、websocket,具体代码如下:

import time
import websocket

class Leyu:
    def __init__(self):
        # 获取token
        self.token = get_token()
        # 初始化服务器地址
        self.ws_url = 'ws://push.611.com:6118/{}'.format(self.token)
        # 初始化websocket
        self.socket = websocket.WebSocketApp(
            self.ws_url,
            on_message=self.on_message,
            on_error=self.on_error,
            on_close=self.on_close,
            on_open=self.on_open
        )

    def login(self):
        # 向服务器发送连接信息
        msg = '{"command":"RegisterInfo","action":"Web","ids":[],"UserInfo":{"Version":"[' + str(int(time.time())) + '000' + ']\
        {\\"chrome\\":true,\\"version\\":\\"106.0.0.0\\",\\"webkit\\":true}","Url":"https://live.611.com/"}}'
        self.socket.send(msg)

    def join_group(self):
        # 向服务器发送入组信息
        msg1 = '{"command":"JoinGroup","action":"SoccerLive","ids":[]}'
        msg2 = '{"command":"JoinGroup","action":"BasketSoccerLive","ids":[]}'
        self.socket.send(msg1)
        self.socket.send(msg2)

    def on_message(self, ws, message):
        # 输出服务器推送过来的内容
        print(message)

    def on_error(self, ws, error):
        # 报错
        print('报错:', error)

    def on_close(self, ws, *args):
        # 关闭连接
        print("####### on_close #######")

    def on_open(self, *args):
        # 连接服务器
        self.login()
        print('连接成功!')
        self.join_group()

    def run(self):
        # 运行循环
        self.socket.run_forever()
if __name__ == '__main__':
    ly = Leyu()
    ly.run()

运行:其学习的过程中踩了不少的坑,能真正跑起的案例可唯是凤毛麟角。不知道是因为大佬们用的版本不一样,还是什么问题。
Python爬虫:Python+WebSocket获取体育实时赛事数据_第5张图片Python爬虫:Python+WebSocket获取体育实时赛事数据_第6张图片


通过推测试一个列表字典里的分别为A队和B队的比分,分成了三个列表,然后实时更新数据。

另扩展:
连接websocket还有一个异步库可以用,aiowebsocket

import time
import websocket

import asyncio
import requests
import logging
import time
from aiowebsocket.converses import AioWebSocket

# 爬虫网址 http://m.611.com/


def get_token():
    # 获取token
    token_url = 'http://m.611.com/Live/GetToken'
    headers = {
        'Accept': '*/*',
        'Accept-Language': 'zh-CN,zh;q=0.9',
        'Connection': 'keep-alive',
        'Referer': 'http://m.611.com/',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',
        'X-Requested-With': 'XMLHttpRequest'
    }
    return requests.get(token_url, headers=headers, verify=False).json()['Data']


async def startup(uri):
    async with AioWebSocket(uri) as aws:
        converse = aws.manipulator
        # 向服务器发送消息
        await converse.send('{"command":"RegisterInfo","action":"Web","ids":[],"UserInfo":{"Version":"[' + str(int(time.time())) + '000' + ']\
        {\\"chrome\\":true,\\"version\\":\\"106.0.0.0\\",\\"webkit\\":true}","Url":"https://live.611.com/"}}')
        await converse.send('{"command":"JoinGroup","action":"SoccerLive","ids":[]}')
        await converse.send('{"command":"JoinGroup","action":"BasketSoccerLive","ids":[]}')
        while True:
            mes = await converse.receive()
            print(mes)
            print("================*================")


if __name__ == '__main__':
    token = get_token()
    remote = 'ws://push.611.com:6118/{}'.format(token)
    try:
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        loop.run_until_complete(startup(remote))
        # asyncio.get_event_loop().run_until_complete(startup(remote))
    except KeyboardInterrupt as exc:
        logging.info('Quit.')

总结:
整个过程其实就是分析,分析数据获取方式,分析链接,分析参数,代码写起来就比较容易了。这个网站貌似没什么反爬措施,作为一个练手的项目还是不错的。

你可能感兴趣的:(python,爬虫,websocket)