1. 背景
在视频网站上,一边看视频一边发弹幕已经是网友的习惯。在B站上有很多种类的视频,也聚集了各种爱好的网友。本项目,就是对B站弹幕数据进行分析。选取分析的对象是B站上点播量过1.4亿的一部剧《Re:从零开始的异世界生活》。
2.算法
分两部分:
第一部分:
2.1在《Re:从零开始的异世界生活》的首页面,找到共25集的所有对应播放链接和剧名的格式,获取每一集的播放链接,并保存。
2.2从每一集的播放页面中,通过正则re获取它的cid号,获得cid号后,就可用于获取弹幕文件。由于是动态页面,所以使用了selenium库的PhantomJS()方法。
2.3因为b站需要通过格式为:https://comment.bilibili.com/dmroll,{time},{cid}的链接获取弹幕历史文件,所以要获取30天内的弹幕历史,就要计算出最近30天的时间戳。最后将组装好的url保存到history_danmu_url.txt文件。
2.4当弹幕文件的url准备完成后,就可以通过静态页面的获取方法requests.get(url)获取弹幕页面。所有的弹幕历史格式:刀还是没有枪快
2.5p这个字段里面的内容:(资料来自百度搜索)
0,1,25,16777215,1312863760,0,eff85771,42759017中几个逗号分割的数据
第一个参数是弹幕出现的时间以秒数为单位。
第二个参数是弹幕的模式1..3滚动弹幕4底端弹幕5顶端弹幕6.逆向弹幕7精准定位8高级弹幕
第三个参数是字号,12非常小,16特小,18小,25中,36大,45很大,64特别大
第四个参数是字体的颜色以HTML颜色的十进制为准
第五个参数是Unix格式的时间戳。基准时间为1970-1-1 08:00:00
第六个参数是弹幕池0普通池1字幕池2特殊池【目前特殊池为高级弹幕专用】
第七个参数是发送者的ID,用于“屏蔽此弹幕的发送者”功能
第八个参数是弹幕在弹幕数据库中rowID用于“历史弹幕”功能。
2.6逐个弹幕历史文件爬取,将内容一集的30天的弹幕历史,以['dtTime', 'danmu_model', 'font', 'rgb', 'stamp','danmu_chi', 'userID', 'rowID', 'message', 'episode']的格式保存到d1.csv,d2.csv,d3.csv,……的文件中
2.7除了将30天的所有历史弹幕保存在一起外,爬虫程序,还将每一集视频,在B站的最新弹幕历史文件的内容单独保存在文件名格式为now1.csv,now2.csv,……的文件中。获取最新弹幕历史文件的链接格式是:https://comment.bilibili.com/{cid}.xml,它们已经被保存在”comment.txt”文件。
第二部分:
2.8保存了所有的数据后,对数据进行处理:先读取.csv文件,然后进行可视化分析:
2.8.1每集弹幕总量的变化图
逐个读入弹幕历史文件:d1.csv,d2.csv,……经过去重后,统计出每集的弹幕总量:
data = pd.read_csv(item.strip(),encoding='gbk')
统计每一集,近30天,弹幕总量,保存在字典:{1:323233,2:212121,.......}
episode_comment_dic[data.loc[1,'episode']] = every_episode_comment(data)
2.8.2发弹幕总量top5用户
a.统计每一集,30天内的弹幕数量,依据弹幕数量,把用户排序,每一集排序后的结果是一个DataFrame:
结果的大致结构:user_sort_dic = {1: DataFrame1, 2:DataFrame2, ......,25: DataFrame25}。
user_sort_dic[data.loc[1, 'episode']] =every_episode_usersort(data)
b.把经过排序统计处理后的所有DataFrame进行concat。然后就可以统计所有用户在30天内,对25集视频发送弹幕的数量。最后对用户排序。最终结果:d4_alldanmu_sort是一个DataFrame变量,将用户按弹幕数,降序排列。
d3_all_user = (pd.concat([item for k, itemin user_sort_dic.items()]))
d3_all_user['userID'] = d3_all_user.index
aSer =d3_all_user.groupby('userID').episode.sum()
d4_alldanmu_sort =pd.DataFrame(aSer).sort_values(by='episode', ascending=False)
2.8.3用户发弹幕长度分布
统计发送弹幕的字符串长度。
danmu_length_dic[data.loc[1,'episode']] = static_danmu_length(data)
2.8.4用户发弹幕数量分布
统计一集,用户发送弹幕数量的百分比分布图。
d_tmp = user_sort_dic[i] #统计用户排名时已经有数据了
every_episode_danmu_pie(d_tmp, i)
2.8.5每集弹幕密度变化图
弹幕都有一个时间参数,代表了在视频的什么时间发了弹幕。可以统计出在相同时间参数发出的弹幕量,然后再画出“时间--弹幕”折线图,就可以看到弹幕量的变化了。
2.8.6每集热词画出词云
对每一集的弹幕文本进行分析。先用jieba词库进行分词,然后逐行对弹幕进行词频统计,最后用WordCloud画出词云图。
3.安装
使用的是anaconda的环境。所以直接在anaconda里进行安装:
pip install -ihttps://pypi.tuna.tsinghua.edu.cn/simple jieba
conda –c https://conda.anaconda.org/conda-forge wordecloud #词云只支持到python3.4
4.统计结果
4. 1每集弹幕总量变化
4.2 发送弹幕总量top5用户
4.3 用户发送弹幕长度分布
4.4 用户发送弹幕数量分布
4.5 每集弹幕密度分布图
4.6 每集的词云
5.结果分析
通过以上的图表数据可以看出用户的弹幕的一些行为。
5.1 25集剧里,第一集和最后一集,弹幕数量是最多的,这和其他剧的开头和结尾两部的一样。中间的18集也获得了很多的弹幕数,原来是在那集里剧情出现了很大的变化,吸引了大家的讨论。
5.2统计了25部剧,用户ID为356ed98的用户共发送了580多条弹幕,算是超级粉丝了。
5.3通过弹幕数量和长度的分布,可以看出:
绝大部分用户只会发送2条以内的弹幕。
参与弹幕讨论的用户以10个字符以内的短语为主。
5.4统计每一集的弹幕密度,可以通过用户观看时的讨论,大致确定视频的精彩点。
5.5通过词云图,可以大致看出用户的分布。例如第一集里“重温”作为热词显示里。说明现在有很多用户是会多次观看这部剧的。
6. 参考代码
6.1 爬虫部分:
# -*- coding: utf-8 -*-
"""
Created on Mon Jul 10 16:34:27 2017
@author: ahchpr
filename: re_zero_bili.py
"""
import requests, csv, re, time
from bs4 import BeautifulSoup as BS
from selenium import webdriver
import datetime
from multiprocessing import Pool
import sys
# Re:从零开始的异世界生