This repository has been archived by the owner on Jul 25, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
/
douyu.py
134 lines (111 loc) · 4.64 KB
/
douyu.py
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#coding:utf-8
#爬取斗鱼弹幕
import socket,re,time,threading,urllib.request,json,urllib.parse,random
class douYuTVDanmu(object):
def __init__(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.codeLocalToServer = 689
self.serverToLocal = 690
self.gid = -9999
self.rid = 16789
self.server = {}
def log(self,str):
#str = str.encode()
now_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
log = now_time + '\t\t' + str
with open('log.txt','a',encoding='utf-8')as f:
f.writelines(log + '\n')
print(log)
def sendMsg(self,msg):
msg = msg.encode('utf-8')
data_length= len(msg)+8
msgHead=int.to_bytes(data_length,4,'little')+int.to_bytes(data_length,4,'little')+int.to_bytes(self.codeLocalToServer,4,'little')
self.sock.send(msgHead)
self.sock.sendall(msg)
def keeplive(self):
while True:
msg='type@=keeplive/tick@='+str(int(time.time()))+'/\x00'
self.sendMsg(msg)
#keeplive=sock.recv(1024)
time.sleep(20)
#分析网页中的信息
def getInfo(self,url):
self.log("请求网页内容...")
try:
with urllib.request.urlopen(url)as f:
data = f.read().decode()
except BaseException as e:
self.log("请求网页内容失败...")
exit(404)
self.log("获取房间信息...")
room = re.search('var \$ROOM = (.*);',data)
if room:
room = room.group(1)
room = json.loads(room)
self.log("房间名:"+room["room_name"]+'\t\t|\t\t主播:'+room["owner_name"])
self.rid = room["room_id"]
if room["show_status"] == 2:
self.log("未开播!\t\t"+str(self.rid))
exit(1)
# self.log("获取弹幕服务器信息...")
# server_config = re.search('server_config":"(.*)","de',data)
# if server_config:
# server_config = server_config.group(1)
# server_config = urllib.parse.unquote(server_config)
# server_config = json.loads(server_config)
# self.server = server_config
def connectToDanMuServer(self):
#index = random.randint(0,len(self.server)-1) #选择一个服务器
# HOST = self.server[index]['ip']
# PORT = self.server[index]['port']
HOST = 'openbarrage.douyutv.com'
PORT = 8601
self.log("连接弹幕服务器..."+HOST+':'+str(PORT))
self.sock.connect((HOST, PORT))
self.log("连接成功,发送登录请求...")
#抓包:msg = 'type@=loginreq/username@=qq_NEUBLK/password@=1234567890123456/roomid@=335166/'
msg = 'type@=loginreq/username@=/password@=/roomid@='+str(self.rid)+'/\x00'
self.sendMsg(msg)
data = self.sock.recv(1024)
self.log('Received from login\t\t'+ repr(data))
a = re.search(b'type@=(\w*)', data)
if a.group(1)!=b'loginres':
self.log("登录失败,程序退出...")
exit(0)
self.log("登录成功")
#data = self.sock.recv(1024) #type@=msgrepeaterlist 服务器列表
#self.log('msgrepeaterlist\t\t'+ repr(data))
# gid = re.search('gid@=(.*)\/',data)
# # data = self.sock.recv(1024)
# # self.log('Received', repr(data))
# if gid:
# self.gid = gid.group(1)
# self.log("找到弹幕服务器"+str(self.gid))
msg = 'type@=joingroup/rid@='+str(self.rid)+'/gid@=-9999/\x00'
#print(msg)
self.sendMsg(msg)
self.log("进入弹幕服务器...")
threading.Thread(target=douYuTVDanmu.keeplive,args=(self,)).start()
self.log("心跳包机制启动...")
data = self.sock.recv(1024)
print('Received', repr(data))
def danmuWhile(self):
self.log("监听中")
while True:
data = self.sock.recv(1024)
#self.log(repr(data))
a = re.search(b'type@=(\w*)', data)
if a:
if a.group(1)==b'chatmsg':
danmu = re.search(b'nn@=(.*)/txt@=(.*?)/',data)
#self.log(danmu.group(1).decode()+'\t:\t'+danmu.group(2).decode())
try:
self.log(danmu.group(2).decode())
except BaseException as e:
self.log("\t\t_________解析弹幕信息失败:"+str(data))
if __name__ == '__main__':
url = 'http://www.douyu.com/301712'
danmu = douYuTVDanmu()
danmu.getInfo(url)
danmu.connectToDanMuServer()
danmu.danmuWhile()