斗鱼直播间弹幕爬取2020年最新python
生活随笔
收集整理的這篇文章主要介紹了
斗鱼直播间弹幕爬取2020年最新python
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
PyMySQL==0.9.3
websocket_client==0.57.0
斗魚直播間彈幕2020年最新
? ? 我最近在學習python的直播間彈幕爬取,但是由于斗魚官方把第三方api的接口改變了,必須要注冊為開發者才能使用官方提供的方法進行彈幕爬取。所以我通過搜索教程了解到可以使用瀏覽器自帶的爬取功能對彈幕進行爬取。
原理如下:
利用websocket建立wss 連接
wss://danmuproxy.douyu.com:8506/'
8501-8507都可以使用。
發送登錄信息
發生入組信息
發送心跳數據,(和b站不一樣更高級了,有心跳數據了)。
利用wss必須對發送包進行加密,對接收的數據進行解包,
這些操作官方api 有提供,所以我就不再進行解釋了。
就能返回彈幕數據。完整代碼如下,將roomid?=?"666743" 改成你需要的id。
以下代碼并非我獨創,有借鑒別人的。
import websocket import threading import time class DyDanmuMsgHandler:# 將字符串數據按照斗魚協議封裝為字節流def dy_encode(self,msg):# 頭部8字節,尾部1字節,與字符串長度相加即數據長度# 為什么不加最開頭的那個消息長度所占4字節呢?這得問問斗魚^^data_len = len(msg) + 9# 字符串轉化為字節流msg_byte = msg.encode('utf-8')# 將數據長度轉化為小端整數字節流len_byte = int.to_bytes(data_len, 4, 'little')# 前兩個字節按照小端順序拼接為0x02b1,轉化為十進制即689(《協議》中規定的客戶端發送消息類型)# 后兩個字節即《協議》中規定的加密字段與保留字段,置0send_byte = bytearray([0xb1, 0x02, 0x00, 0x00])# 尾部以'\0'結束end_byte = bytearray([0x00])# 按順序拼接在一起data = len_byte + len_byte + send_byte + msg_byte + end_bytereturn datadef __parse_msg(self,raw_msg):'''解析數據:param raw_msg: 原始response數據:return:'''res = {}attrs = raw_msg.split('/')[0:-1]for attr in attrs:attr = attr.replace('@s','/')attr = attr.replace('@A','@')couple = attr.split('@=')res[couple[0]] = couple[1]return resdef dy_decode(self,msg_byte):'''解析斗魚返回的數據:param msg_byte::return:'''pos = 0msg = []while pos < len(msg_byte):content_length = int.from_bytes(msg_byte[pos: pos + 4], byteorder='little')content = msg_byte[pos + 12: pos + 3 + content_length].decode(encoding='utf-8', errors='ignore')msg.append(content)pos += (4 + content_length)return msgdef get_chat_messages(self,msg_byte):'''從數據獲取chatmsg數據:param msg_byte::return:'''decode_msg = self.dy_decode(msg_byte)messages = []for msg in decode_msg:res = self.__parse_msg(msg)if res['type'] !='chatmsg':continuemessages.append(res)return messages class DyDanmuCrawler:def __init__(self,roomid):self.__room_id = roomidself.__heartbeat_thread = Noneself.__client = DyDanmuWebSocketClient(on_open=self.__prepare,on_message=self.__receive_msg,on_close=self.__stop)self.__msg_handler = DyDanmuMsgHandler()self.__keep_HeartBeat = Truedef start(self):'''開啟客戶端:return:'''self.__client.start()def __stop(self):'''登出停止客戶端停止心跳線程:return:'''self.__logout()self.__client.stop()self.__keep_HeartBeat=Falsedef on_error(self, error):print(error)def on_close(self):print('close')# 發送入組消息def join_group(self):'''發送群組消息:return:'''join_group_msg = 'type@=joingroup/rid@=%s/gid@=1/' % (self.__room_id)msg_bytes = self.__msg_handler.dy_encode(join_group_msg)self.__client.send(msg_bytes)# 發送登錄請求消息def login(self):'''登陸:return:'''login_msg = 'type@=loginreq/roomid@=%s/dfl@=sn@AA=105@ASss@AA=1/' \'username@=%s/uid@=%s/ver@=20190610/aver@=218101901/ct@=0/.'%(self.__room_id,'99047358','99047358')msg_bytes = self.__msg_handler.dy_encode(login_msg)self.__client.send(msg_bytes)def __start_heartbeat(self):self.__heartbeat_thread = threading.Thread(target=self.__heartbeat)self.__heartbeat_thread.start()def __heartbeat(self):heartbeat_msg = 'type@=mrkl/'heartbeat_msg_byte = self.__msg_handler.dy_encode(heartbeat_msg)while True:self.__client.send(heartbeat_msg_byte)for i in range(90):time.sleep(0.5)if not self.__keep_HeartBeat:returndef __prepare(self):self.login()# 登錄后發送入組消息self.join_group()self.__start_heartbeat()def __receive_msg(self, msg):'''處理收到的信息:param msg::return:'''chat_messages =self.__msg_handler.get_chat_messages(msg)for message in chat_messages:print(f"{message['nn']}:{message['txt']}")# 將字節流轉化為字符串,忽略無法解碼的錯誤(即斗魚協議中的頭部尾部)#print(message.decode(encoding='utf-8', errors='ignore'))class DyDanmuWebSocketClient:def __init__(self,on_open,on_message,on_close):self.__url ='wss://danmuproxy.douyu.com:8506/'self.__websocket = websocket.WebSocketApp(self.__url,on_open=on_open,on_message=on_message,on_error=self.__on_error,on_close=on_close)def start(self):self.__websocket.run_forever()def stop(self):self.__websocket.close()def send(self,msg):self.__websocket.send(msg)def __on_error(self,error):print(error)roomid = "666743" dy_barrage_crawler = DyDanmuCrawler(roomid) dy_barrage_crawler.start()總結
以上是生活随笔為你收集整理的斗鱼直播间弹幕爬取2020年最新python的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql5.0 java连接_Java
- 下一篇: 2021辽宁大洼高中高考成绩查询,202