Python實時爬取鬥魚彈幕
Python實時爬取鬥魚彈幕
實現目標:
輸入鬥魚房間號實時獲取彈幕資訊,實現效果如下:
douyu.gif
邏輯梳理
- 首先說明下鬥魚是開放了彈幕API的,可以直接去他們開發者論壇檢視文件,按照文件中要求一步一步的來就好了,我這邊就簡單梳理下:
- 建立兩個執行緒:一個與彈幕伺服器建立連線然後獲取資料,一個定時傳送心跳資訊給彈幕伺服器保持連線。
建立連線
- 通過TCP協議連線到彈幕伺服器;
IP 地址:openbarrage.douyutv.com 埠:8601
- 向彈幕伺服器傳送登入請求,登入彈幕伺服器,訊息格式
type@=loginreq/roomid@=房間號/
,不需要賬號密碼; - 登陸成功之後伺服器會給你返回一個登入成功資訊,這部分不用管,繼續向伺服器傳送一個進入彈幕分組請求,格式
type@=joingroup/rid@=房間號/gid@=-9999/
,gid使用-9999就好,表示海量彈幕模式; - 接下來接收訊息就好了,當然伺服器返回的不止彈幕資訊,還包括禮物/特殊人物進入房間等訊息,這部分可以通過返回訊息的type進行判斷,選擇自己需要的就好,詳細的參見文件;
心跳訊息
- 為保持連線需要每隔段時間向彈幕伺服器傳送心跳訊息,長時間未收到心跳訊息伺服器就會斷開連線了,心跳訊息格式:
type@=keeplive/tick@=1439802131/
,其中tick為當前秒級時間戳。
程式碼部分
# -*- coding:utf-8 -*-
import socket
import re
import time
import struct
import threading
def connect():
'''
第三方客戶端通過 TCP 協議連線到彈幕伺服器(依據指定的 IP 和埠);
第三方接入彈幕伺服器列表:
IP 地址:openbarrage.douyutv.com 埠:8601
'''
print '-----*-----DouYu_Spider-----*-----\n'
host = socket.gethostbyname("openbarrage.douyutv.com")
port = 8601
global s
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
def send_msg(msg):
data_length = len(msg) + 8
code = 689
msgHead = struct.pack('<i',data_length) \
+ struct.pack('<i',data_length) + struct.pack('<i',code)
s.send(msgHead)
sent = 0
while sent < len(msg):
tn = s.send(msg[sent:])
sent = sent + tn
def danmu(room_id):
'''
1.客戶端向彈幕伺服器傳送登入請求
2.客戶端收到登入成功訊息後傳送進入彈幕分組請求給彈幕伺服器
'''
login = 'type@=loginreq/roomid@=%s/\0'%room_id
login = login.encode('utf-8')
send_msg(login)
joingroup = 'type@=joingroup/rid@=%s/gid@=-9999/\0'%room_id
joingroup = joingroup.encode('utf-8')
send_msg(joingroup)
while True:
content = s.recv(1024)
if judge_chatmsg(content):
nickname = nick_name(content)
chatmsg = chat_msg(content)
print '%s : %s'%(nickname,chatmsg)
else:
pass
def keep_alive():
'''
客戶端每隔 45 秒傳送心跳資訊給彈幕伺服器
'''
while True:
msg = 'type@=keeplive/tick@=%s/\0'%str(int(time.time()))
send_msg(msg)
time.sleep(45)
def nick_name(content):
'''
彈幕訊息:
type@=chatmsg/rid@=301712/gid@=-9999/uid@=123456/nn@=test /txt@=666/level@=1/
判斷type,彈幕訊息為chatmsg,txt為彈幕內容,nn為使用者暱稱
'''
pattern = re.compile(r'nn@=(.*)/txt@')
nickname = pattern.findall(content)[0]
return nickname
def chat_msg(content):
'''
彈幕訊息:
type@=chatmsg/rid@=301712/gid@=-9999/uid@=123456/nn@=test /txt@=666/level@=1/
判斷type,彈幕訊息為chatmsg,txt為彈幕內容,nn為使用者暱稱
'''
pattern = re.compile(r'txt@=(.*)/cid@')
chatmsg = pattern.findall(content)[0]
return chatmsg
def judge_chatmsg(content):
'''
判斷是否為彈幕訊息
'''
pattern = re.compile(r'type@=(.*)/rid@')
data_type = pattern.findall(content)
try:
if data_type[0] == 'chatmsg':
return True
else:
return False
except Exception, e:
return False
if __name__ == '__main__':
connect()
t1 = threading.Thread(target=danmu,args=(2947432,))
t2 = threading.Thread(target=keep_alive)
t1.start()
t2.start()
最後
鬥魚提供的文件已經是一年前的了,裡面傳回的訊息內容增加了不少,但整體邏輯還是沒變,我這邊只取了彈幕裡面的暱稱和文字內容,其他的訊息各位可以先列印出來看了再寫正規表示式去匹配就好。
相關文章
- 鬥魚彈幕資料爬取
- ? 鬥魚彈幕php實現PHP
- Flutter 實現虎牙/鬥魚 彈幕效果Flutter
- Android彈幕功能實現,模仿鬥魚直播的彈幕效果Android
- Web實時彈幕原理分析Web
- 教你用python爬蟲爬blibili網站彈幕!Python爬蟲網站
- 淘寶直播彈幕爬蟲爬蟲
- MARS預賽:鬥魚直播網路火爆 彈幕大神齊上陣
- python 爬蟲 實現增量去重和定時爬取例項Python爬蟲
- Python如何爬取實時變化的WebSocket資料PythonWeb
- python爬蟲獲取天氣網實時資料Python爬蟲
- Python實現微博爬蟲,爬取新浪微博Python爬蟲
- 爬蟲——爬取貴陽房價(Python實現)爬蟲Python
- 彈幕不擋人!基於色鍵技術的純客戶端實時蒙版彈幕客戶端
- Python爬蟲實戰:爬取淘寶的商品資訊Python爬蟲
- Python爬蟲實踐--爬取網易雲音樂Python爬蟲
- Python網路爬蟲第三彈《爬取get請求的頁面資料》Python爬蟲
- bilibili高併發實時彈幕系統的實戰之路
- Python爬蟲實戰詳解:爬取圖片之家Python爬蟲
- Python3.X 爬蟲實戰(併發爬取)Python爬蟲
- 實時獲取股票資料,免費!——Python爬蟲Sina Stock實戰Python爬蟲
- Python爬蟲實戰一:爬取csdn學院所有課程名、價格和課時Python爬蟲
- Python爬蟲實戰案例-爬取幣世界標紅快訊Python爬蟲
- Python爬蟲-用Scrapy框架實現漫畫的爬取Python爬蟲框架
- MOJITO 釋出一週,爬一波彈幕分析下
- Go使用websocket實現彈幕功能GoWeb
- 實現播放視訊及彈幕
- 自定義簡單彈幕實現
- python 爬蟲 爬取 learnku 精華文章Python爬蟲
- python爬蟲——爬取大學排名資訊Python爬蟲
- WebComponent+WebGl的實時影象處理彈幕播放器Web播放器
- python爬蟲實戰:爬取西刺代理的代理ip(二)Python爬蟲
- Python爬蟲實戰-使用Scrapy框架爬取土巴兔(一)Python爬蟲框架
- python爬取網圖Python
- python爬蟲抓取資料時失敗_python爬蟲 大佬 請教下 為什麼爬取的資料有時能爬到 有時有爬不到, 程式碼如下:...Python爬蟲
- 簡單彈幕第二彈(c3animate實現)
- python爬蟲--爬取鏈家租房資訊Python爬蟲
- Python爬蟲爬取美劇網站Python爬蟲網站