前言:
看直播已经挺久了,正好在这个暑假学习了Python爬虫,所以想尝试分析一下谁才是斗鱼之中观看人数最多的主播。使用Python编写爬虫代码,爬取斗鱼直播间的信息,最后结合Echarts这个神器作出图表。
准备工作:
这次运行的代码仅仅需要requests和BS4,都是Python爬虫比较常见的库,都可以用pip下载。
pip install BeautifulSoup4
pip install requests
pip install pymysql
pip install pyecharts
然后用Mysql存储数据,最后分析和作图表用了Excel和Echarts。
首先我们要分析斗鱼直播的网站结构,不管抓取什么信息都要先分析网页结构,找到我们需要信息的所在地方。
这次我们的目标网站是:
按F12打开chrome的开发者工具,初步分析网站大概的结构,可以看到每一个直播间的信息都在
准备工作做足,接下来就是编写代码了。
代码编写:
import requests
import re
import time
from bs4 import BeautifulSoup
import pymysql
from datetime import datetime
def open_html(url):
r = requests.get(url)
r.encoding = 'utf-8'
return r.text
def scrapy(url):
infos = []
html = open_html(url)
soup = BeautifulSoup(html, 'lxml')
total = soup.find('ul',id='live-list-contentbox')
every = total.find_all('li',attrs={'data-rpos':'0','data-sub_rt':'0'})
for li in every:
#定义一个空字典
info = {}
info['title'] = li.find('h3').text.strip()#找到标题
info['type'] = li.find('span',class_='tag ellipsis').text.strip()#找到直播版块
info['host'] = li.find('span',class_='dy-name ellipsis fl').text.strip()#找到主播
now = datetime.now()
num = li.find('span',class_='dy-num fr').text
if '万' in num:
num1 = num.replace('万','')
if '.' in num1:
num2 = float(num1)*10000
info['viewer'] = num2
else:
num2 = int(num1)*10000
info['viewer'] = num2
else:
info['viewer'] = num
#直播间地址
info['link'] = 'https://www.douyu.com/'+str(li.find('a',class_='play-list-link')['href'])
#当前时间
info['time'] = now
infos.append(info)
print ('一个房间的数据抓取完成')
return infos
def PrintFile(dict):
for want in dict:
title = want['title']
type = want['type']
link = want['link']
host = want['host']
time = want['time']
viewer = want['viewer']
# 和本地的数据库建立连接
connection = pymysql.connect(
host='localhost', # 连接的是本地数据库
user='root', # mysql用户名
passwd='XXXX', # 密码
db='XXXX', # 数据库的名字
charset='utf8', # 默认的编码方式:
cursorclass=pymysql.cursors.DictCursor)
with connection.cursor() as cursor:
# 创建更新值的sql语句
sql = "INSERT INTO 斗鱼(title,type,link,host,viewer,time) VALUES (%s,%s,%s,%s,%s,%s)"
cursor.execute(sql,(title,type,link,host,viewer,time))
# 提交本次插入的记录
connection.commit()
connection.close()
print('所有直播间信息爬取完成')
def main(url):
content = scrapy(url)
PrintFile(content)
print('所有的信息都已经保存完毕!')
url = 'https://www.douyu.com/directory/all'
if __name__ == '__main__':
for i in range(1,20):
main(base_url)
#抓取一次之后休眠半个小时
time.sleep(1800)
使用Mysql数据库除了安装Mysql之外,还可以安装Navicat这个可视化工具,大大降低了使用难度(其实是一开始下载Mysql的时候一脸蒙蔽,完全不知道怎么使用,后来百度知道了还有可视化工具)
安装完之后就新建一个数据库,然后新建一个表格,然后定义所需要的变量名和变量类型。
输出:
结果:
程序一共爬了15天左右,不过并不是连续的,中间中断了几次,每天起床之后就打开程序运行(后来知道还可以把代码放在云服务器运行- -,我是小白只能用笨方法了),最后抓取了大概3.7w条数据。先来看一下观看人数的TOP 20:
好吧- -,观看人数排行榜TOP 20都是英雄联盟比赛的官方直播间,排行第一的是7月30号WE vs RNG的比赛,有792万人次观看。(时隔已经大半个月了,LPL也快要总决赛了)
为了满足好奇心,把比赛直播间的数据剔除,再来看看主播们的观看人数排行榜:
在这份榜单中,只有两个人,五五开和张大仙,都是他们不同直播天数的数据,由于我不怎么玩王者荣耀,所以之前从没注意过张大仙(但是必须承认王者荣耀真的很多人玩,群上每天都约开黑,我只能默默看着他们...)。百度了一下张大仙的资料,原来他原本是企鹅电竞的大主播。张大仙在某些天数的同时段观看人数已经超过了五五开。
不过我们也有了分析方向,张大仙和五五开都属于19点至24点这个时间段的,那就可以来横向比对他们每个时间点的观看人数。
分析:
观看人数:
选取了四天的抓取数据,分别是8月17日、8月10日、8月9日和8月8日。代码设置了每三十分钟运行一次,一共有10个时间点。在这里就要强烈推荐Echarts,属于百度的产品,可以说相较于百度全家桶,这个真是良心产品。而Python的相关库pymysql最近更新了时间线功能Timeline(),官方文档pyecharts详细说明了使用方法,尝试了一下感觉非常酷炫,很直观显示了数据的趋势,可以把多个图表按照时间线在一个图中同时呈现,代码和GIF图如下:
import pyecharts as p
from pyecharts import Timeline
#这些数据是经过excel处理的
attr = ['19:03:00', '19:33:00', '20:03:00', '20:33:00', '21:03:00', '21:33:00',
'22:03:00','22:33:00','23:03:00','23:33:00']
wu1 = [34000,783000,1540000,1150000,1580000,1490000,1630000,1720000,2210000,2120000]
zh1 = [2950000,3020000,2990000,2840000,3040000,2800000,2950000,2800000,2970000,2800000]
line1 = p.Line('8月17号')
line1.add('五五开',attr,wu1)
line1.add('张大仙',attr,zh1,is_smooth=True)
wu2 = [1140000,1640000,1960000,2380000,1890000,1720000,2120000,2850000,3280000,2850000]
zh2 = [2300000,2530000,2770000,2760000,2690000,2690000,2690000,2680000,2760000,2800000]
line2 = p.Line('8月10号')
line2.add('五五开',attr,wu2)
line2.add('张大仙',attr,zh2,is_smooth=True)
wu3 = [1130000,2470000,2730000,2500000,2930000,3330000,3550000,3180000,2780000,2700000]
zh3 = [2100000,2200000,2780000,2800000,2790000,2670000,2830000,2800000,2720000,2810000]
line3 = p.Line('8月9号')
line3.add('五五开',attr,wu3)
line3.add('张大仙',attr,zh3,is_smooth=True)
wu4 = [1140000,1940000,2590000,2550000,2220000,2540000,2660000,2420000,2520000,2450000]
zh4 = [2750000,2720000,2770000,2680000,2850000,2790000,2770000,2700000,2730000,2800000]
line4 = p.Line('8月8号')
line4.add('五五开',attr,wu4)
line4.add('张大仙',attr,zh4,is_smooth=True)
timeline = Timeline(is_auto_play=False, timeline_bottom=0)
timeline.add(line1, '8月17号')
timeline.add(line2, '8月10号')
timeline.add(line3, '8月9号')
timeline.add(line4, '8月8号')
timeline.render()
从图表中我们可以看到张大仙的观看人数简直稳定的可怕,一直保持在260万人次左右,而且看不出开播—直播—关播这样的趋势,分析的时候也一直怀疑自己是否做错了。就算在某些时候五五开的观看人数会超过他,但是总体上看是少于张大仙的。
弹幕:
好,除了观看人数,我们再来看一看另一个指标,那就是弹幕。经过资料查找,发现Python连抓取弹幕的第三方库都有,而且不止一个。这次使用的是danmu,是大神 @LittleCoder 编写的,支持抓取斗鱼、熊猫、b站等直播网站的弹幕。在某一天,从19点49分开始,同时抓取五五开和张大仙的弹幕,在24点12分结束。
先看看代码,代码很简单:
from danmu import DanMuClient
import pymysql
dmc = DanMuClient('https://www.douyu.com/688')
@dmc.danmu
def danmu_fn(msg):
client = msg['NickName']
message = msg['Content']
connection = pymysql.connect(
host='XXXX', # 连接的是本地数据库
user='XXXX', # mysql用户名
passwd='XXXX', # 密码
db='XXXX', # 数据库的名字
charset='utf8mb4', # 默认的编码方式,最好选这个,因为弹幕可能出现表情
cursorclass=pymysql.cursors.DictCursor)
with connection.cursor() as cursor:
# 创建更新值的sql语句
sql = "INSERT INTO 张大仙弹幕(client,message) VALUES (%s,%s)"
cursor.execute(sql,(client,message))
# 提交本次插入的记录
connection.commit()
dmc.start(blockThread = True)
Mysql显示的结果如下:
一页有1000条数据,最后五五开的弹幕一共抓取了166页,弹幕数量约为16.6万(可能因为网络延迟而丢失某些弹幕)。
而张大仙一共抓取了171页,最后一页有859条,那么他的弹幕数量约为17万条。
总结:
从收集到的数据来看,五五开不管是观看人数还是弹幕数量都比张大仙少一点。侧面证明了王者荣耀的玩家确实非常多。但是这也无碍五五开超高人气,毕竟五五开不仅玩英雄联盟,几乎所有热门游戏,五五开都在直播间玩过。
但是仅仅分析观看人数和弹幕是不能准确分析直播间的人气,毕竟还涉及很多其他因素,而且事后的分析没有特别严谨的统计思路和统计方法。这仅仅是我学习Python的一个小实践,没有多大技术含量,很多观点也带有一点个人色彩,只是想分享一下自己的学习经历,给其他人一点思路。
最后说一下:
我的专业不是学计算机的,本科专业是心理学,之前也没有接触过一点编程知识,这个暑假刚刚考研结束,因为选择了心理统计方向,所以想学习一些新东西,导师本来建议我去学学R语言,但是网上都说Python会比较简单和好用,所以最后选择了Python。网上有很多教程,但是大多数对于我这么一个什么都不懂的人来说,真的很难理解,一开始学习的时候一个专业名词就能难倒我,学习Python一直断断续续。
直到我在知乎上看到 @Ehco 的专栏从零开始写Python爬虫,那时候开始就深深爱上Python爬虫,他的教程相比起别人都简单明了,虽然中间还是会遇到很多不懂,但是起码我开始能真正完成一个爬虫程序。整个暑假都是跟着他的教程学习,虽然他不认识我,但是只要他更新了教程,我都会去点赞和学习。没有他的教程也就没有以后的事了,希望自己也能通过不断的学习真正掌握Python。
最近新建立了一个公众号,发现Python还能构建公众号,所以自己折腾也玩了很久,已经实现了自动回复机器人、在线点歌、在线翻译等功能。当然也想满足自己喜欢看直播这个需要,修改了一下上面的代码,回复主播名字就可以查看当前直播信息。
公众号也会分享自己学习Python的经历,有兴趣可以关注一下,一起学习,希望有更多的人会爱上Python。
公众号:everypython