说起来,弹幕这种东西的出现,真的给众多网友带来无数的欢乐源泉。

当然,密集恐惧症患者慎入,毕竟某些视频的弹幕可谓是刷得密密麻麻的。

整个屏幕看的不是剧情,是弹幕。

以前是磕CP很快乐,现在是磕着弹幕也满满快乐。

分分钟带动网络新兴流行语言。

既然是在学Pythobn爬虫技术,那么,我们又能不能通过爬虫抓取这些有意识的弹幕呢?

不如接下来跟着小千一起来学一学吧!

结果的展示:

这里只抓到弹幕内容和发送用户

并输出在终端上,有兴趣的小伙伴

可以在这个基础上接着开发,

搜集弹幕做做数据分析也是很ok的啊!

下面是展示图:

资料的搜集

面向Google编程的我,第一件事当然是键入关键词:「Python弹幕」

吃惊的是,网上已经有了炒鸡完善的弹幕第三方库:「DanMU」

使用起来也是炒鸡简单,十几行代码就能轻松获取直播间的弹幕了,

有兴趣的同学可以去搜索看看。

本着练手和不折腾会死的态度,我还是想尝试自己写一个版本出来,

然后就找到了斗鱼居然开放了Api,

这样的话,只要稍微处理一下,就能愉快的获取想要的信息了。

斗鱼Api接口文档和接入协议

《斗鱼弹幕服务器第三方接入协议v1.4.1》:http://dev-bbs.douyutv.com/forum.php?mod=viewthreadtid=115extra=page%3D1

《斗鱼第三方开放平台API文档v2.1》:http://dev-bbs.douyutv.com/forum.php?mod=viewthreadtid=113extra=page%3D1

仔细观察文档之后,我发现只要自己实现一下协议头,就能接入弹幕服务器了,接着构造弹幕请求,就能实时的获取每一条弹幕了。

请求头的构造

先看文档的要求:

简而言之呢:请求一共分为三个部分:长度,头部,数据部

分别按照文档的要求构造就行,

需要注意的是,获取和返回的类型是都是Bytes代码:

defsend_req_msg(msgstr):

'''构造并发送符合斗鱼api的请求'''

msg=msgstr.encode('utf8')

data_length=len(msg) 8

code=689

#构造协议头

msgHead=int.to_bytes(data_length,4,'little')\

int.to_bytes(data_length,4,'little') \

int.to_bytes(code,4,'little')

client.send(msgHead)

sent=0

whilesent

tn=client.send(msg[sent:])

sent=sent tn

获取弹幕

这里的部分也是按照文档要求写就成

首先发送登录请求

接着每隔固定时间发送【心跳请求】防止断线

defDM_start(roomid):

#构造登录授权请求

msg='type@=loginreq/roomid@={}/\0'.format(roomid)

send_req_msg(msg)

#构造获取弹幕消息请求

msg_more='type@=joingroup/rid@={}/gid@=-9999/\0'.format(roomid)

send_req_msg(msg_more)

whileTrue:

#服务端返回的数据

data=client.recv(1024)

#通过re模块找发送弹幕的用户名和内容

danmu_username=username_re.findall(data)

danmu_content=danmu_re.findall(data)

ifnotdata:

break

else:

foriinrange(0,len(danmu_content)):

try:

#输出信息

print('[{}]:{}'.format(danmu_username[0].decode(

'utf8'),danmu_content[0].decode(encoding='utf8')))

except:

continue

defkeeplive():

'''

保持心跳,15秒心跳请求一次

'''

whileTrue:

msg='type@=keeplive/tick@=' str(int(time.time())) '/\0'

send_req_msg(msg)

print('发送心跳包')

time.sleep(15)

tricky的部分

上面的内容,说起来都不是很难,

但是想要完整的实现需求,

这里需要的知识还是比较多的:

socket相关

正则表达式相关

signal相关

多线程、多进程相关

比如我想要实现捕捉「ctrl c」的信号,

好在我们退出程序的时候,能够正确的处理

这时候就要用到signal相关的知识

说起来,在今天之前,我完全不知道还可以这样用。

总之越是学到后面,

越是会觉得自己的知识储备不足,

Python作为一门十分强大和容易上手的语言,

能够帮助我们迅速的实现需求,

但是不要认为他单单只能写爬虫哦~

完整的代码

有详细的注释哦:

'''

利用斗鱼弹幕api

尝试抓取斗鱼tv指定房间的弹幕

'''

importmultiprocessing

importsocket

importtime

importre

importsignal

#构造socket连接,和斗鱼api服务器相连接

client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

host=socket.gethostbyname("openbarrage.douyutv.com")

port=8601

client.connect((host,port))

#弹幕查询正则表达式

danmu_re=re.compile(b'txt@=(. ?)/cid@')

username_re=re.compile(b'nn@=(. ?)/txt@')

defsend_req_msg(msgstr):

'''构造并发送符合斗鱼api的请求'''

msg=msgstr.encode('utf-8')

data_length=len(msg) 8

code=689

#构造协议头

msgHead=int.to_bytes(data_length,4,'little')\

int.to_bytes(data_length,4,'little') \

int.to_bytes(code,4,'little')

client.send(msgHead)

sent=0

whilesent

tn=client.send(msg[sent:])

sent=sent tn

defDM_start(roomid):

#构造登录授权请求

msg='type@=loginreq/roomid@={}/\0'.format(roomid)

send_req_msg(msg)

#构造获取弹幕消息请求

msg_more='type@=joingroup/rid@={}/gid@=-9999/\0'.format(roomid)

send_req_msg(msg_more)

whileTrue:

#服务端返回的数据

data=client.recv(1024)

#通过re模块找发送弹幕的用户名和内容

danmu_username=username_re.findall(data)

danmu_content=danmu_re.findall(data)

ifnotdata:

break

else:

foriinrange(0,len(danmu_content)):

try:

#输出信息

print('[{}]:{}'.format(danmu_username[0].decode(

'utf8'),danmu_content[0].decode(encoding='utf8')))

except:

continue

defkeeplive():

'''

保持心跳,15秒心跳请求一次

'''

whileTrue:

msg='type@=keeplive/tick@=' str(int(time.time())) '/\0'

send_req_msg(msg)

print('发送心跳包')

time.sleep(15)

deflogout():

'''

与斗鱼服务器断开连接

关闭线程

'''

msg='type@=logout/'

send_req_msg(msg)

print('已经退出服务器')

defsignal_handler(signal,frame):

'''

捕捉ctrl c的信号即signal.SIGINT

触发hander:

登出斗鱼服务器

关闭进程

'''

p1.terminate()

p2.terminate()

logout()

print('Bye')

if__name__=='__main__':

#room_id=input('请输入房间ID:')

#狗贼的房间号

room_id=208114

#开启signal捕捉

signal.signal(signal.SIGINT,signal_handler)

#开启弹幕和心跳进程

p1=multiprocessing.Process(target=DM_start,args=(room_id,))

p2=multiprocessing.Process(target=keeplive)

p1.start()

p2.start()

说真的,Python爬虫技术的运用及其广泛,不仅仅是可以在我们日常生活中提供不少便利。

Python爬虫可以做的事情很多,如搜索引擎、采集数据、广告过滤等,Python爬虫还可以用于数据分析,在数据的抓取方面可以作用巨大!

想要进一步系统掌握编程的技术点,但是又找不到靠谱的视频教程,也可以留言跟我索取哦!