美文网首页
龙珠直播弹幕爬取

龙珠直播弹幕爬取

作者: 隐墨留白 | 来源:发表于2019-11-11 11:35 被阅读0次

    第一步,找到龙珠弹幕的websocke接口

    步骤如下:

    • 在龙珠首页,随意进入一个直播间;
    • 按F12,然后刷新网页,点击WS选项;
    • 点击出现websocket接口,选择右边的Headers,查看完整的url。


      1.png

    第二步,分析接口

    如上图所见,接口是拼接而成的,拼接的字段如下:


    2.png

    如果你在多看看其他直播间的接口你就会发现,其中appId,roomId,token的数据是会变化的,那么这些数据都是怎么来的呢?

    通过抓包发现,对一个url请求之后上述所需要的数据都会被返回。 url_data.png
    这个url中唯一变动的就是roomid数据了,所以我们需要先拿到roomid号。通过对当前页面的分析,roomid已经在当前页面的HTML中出现了,所以只需要将roomid匹配出来就好了。

    新建getdata.py文件,获取websocket接口所需数据信息。

    import requests
    import re
    import json
    
    def get_token(url0):
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36',      
        }
        # 获取当前页面HTML信息
        html = requests.get(url=url0,headers=headers).content.decode()
        roominfo = re.findall('roomInfo = (.*?);',html)[0]
        # 获取roomid信息
        roodid = json.loads(roominfo)['RoomId']
    
        url = f'http://mbgo.longzhu.com/zhongtai/checkRoom?roomid={roodid}&wangsu=1&lzv=1'
        headers['Referer'] = url0
    request_data = json.loads(requests.get(url=url,headers=headers).content.decode())['data']
        # 获取token信息
        token = request_data['zhongtaiToken']
        # 获取appId信息
        appId = request_data['appId']
        return appId,roodid,token
    

    第三步,分析推送数据

    点击Message,查看客户端与服务器端的数据交互,分析是如何保持通信连接的。


    3.png

    通过上图,可以看到是服务器进行的无脑数据推送,而客户端发送的信息最多的是一种类型的数据,这应该是就是维持长连接所需要的心跳包。而且如果细心的话就会发现心跳包里面的body所对应的值会出现在上一条服务器端发送的信息中,我们拿过来用就行了。

    import asyncio
    import json
    from aiowebsocket.converses import AioWebSocket
    from getdata import get_token
    
    # 分析弹幕数据,将有用信息提取出来
    def manage_danmu(message):
        content = message['msg']['msg']
        # 弹幕
        if content.get('content'):
            print(content['user']['username'] + ':' + content['content'])
        # 新进直播间
        elif content.get('userMessage'):
            print(content['user']['username'] + ':' + content['userMessage'])
        # 礼物
        elif content.get('title'):
            if content.get('user'):
                print(content['user']['username'] + '送了:' + content['title'])
            else:
                print(content['sourceUserName'] + '送了:' + content['title'])
        # 礼物
        elif content.get('name'):
            print(content['user']['username'] + '送了:' + content['name'])
        else:
            print(content)
            print('*' * 10)
    
    async def startup(uri,f):
        async  with AioWebSocket(uri) as aws:
            converse = aws.manipulator
            n = 0
            while True:
                mes = await converse.receive()
                mes = mes.decode()
                # 将获得的数据写入文件中
                f.write(mes+'\n')
                mes_json = json.loads(mes)
                manage_danmu(mes_json)
                n += 1
                # 每三次发送一次不带msgid的数据信息
                if n == 3:
                    await converse.send( '{"body":"{}","op":2,"sid":0,"seq":0}  ')
                    n = 0
                else:
                    mid = mes_json['msgId']
                    await converse.send('{"body":{"msgId":"%s"},"op":6,"sid":0,"seq":0}     '%mid)
                
    
    if __name__ == '__main__':
        # 进入直播间的url
        url = 'http://star.longzhu.com/y198835?from=filivehot1'
        appid,roomid,token = get_token(url)
       # 拼接websocket接口
        remote = f'ws://ws52.longzhu.com:8805/?appId={appid}&roomId={roomid}&msgVersion=1.0&token={token}'
        with open('data.txt','w',encoding='utf-8')as f:
            try:
                asyncio.get_event_loop().run_until_complete(startup(remote,f))
            except KeyboardInterrupt as exc:
                print(exc)
    

    结果:


    4.png

    通过对比还发现了一个问题,收到的数据有时候会重复,那就只能在数据处理的时候去重了。

    相关文章

      网友评论

          本文标题:龙珠直播弹幕爬取

          本文链接:https://www.haomeiwen.com/subject/kfozbctx.html