精华内容
下载资源
问答
  • 基于简单统计的b站弹幕情感分析

    千次阅读 2019-04-07 11:25:29
    第一步,先把弹幕下载下来 def danmu(urls): global wordlist global av for i in urls: url2='http://comment.bilibili.com/' html=requests.get(i,headers=head) html.encoding='utf-8' ...

    第一步,先把弹幕下载下来

    def danmu(urls):
        global wordlist
        global av
        for i in urls:
            url2='http://comment.bilibili.com/'
            html=requests.get(i,headers=head)
            html.encoding='utf-8'
    
            m=re.findall('"cid":([0-9]+),"dimension":',html.text)
    
            if len(m)>0:
                av.append(i)
                html1=requests.get(url2+m[0]+'.xml')
                html1.encoding='utf-8'
                return html1.text
    

    返回的数据是xml格式的,用ET.fromstring(xml) 解析

    root = ET.fromstring(xml)
    

    根据预先定义好的情绪对照表构建词典

    xls= xlrd.open_workbook('弹幕多维情感词典.xlsx')
    table = xls.sheets()[0]
    nrows = table.nrows  #获取该sheet中的有效行数
    table.cell(1,0)
    m={}
    for i in range(nrows):
        if i==0:
            continue
        else:
           
            m[ str(table.cell(i,1)).replace('text:','').replace('\'','')]= str(table.cell(i,0)).replace('text:','').replace('\'','')
    

    识别每一条弹幕的情绪分类

    def d(s):
        global m
        p=[]
        for i in m.keys():
            if i in s:
                p.append(m[i])
            else:
                p.append('无')#无态度
        return p
    

    提取数据到data,以字典的形式存储

    for i in root.findall('d'):
        if i.attrib['p'].split(',')[0] in data:
            data[float(i.attrib['p'].split(',')[0])]+=d(i.text)
        else:
            data[float(i.attrib['p'].split(',')[0])]=d(i.text)
    

    统计各个情绪的数量

    for i in range(0,round((max(data.keys()))),30):
        x_.append(i/30)
        y1,y2,y3,y4,y5,y6,y7,y8=0,0,0,0,0,0,0,0#乐好怒哀惧恶惊 无
        for j in data.keys():
            if float(i)<float(j) and float(j)<float(i+30):
                for k in data[j]:
                    y1+=k.count('乐')
                    y2+=k.count('好')
                    y3+=k.count('怒')
                    y4+=k.count('哀')
                    y5+=k.count('惧')
                    y6+=k.count('恶')
                    y7+=k.count('惊')
                    y8+=k.count('无')
        
        y_1.append(y1)
        y_2.append(y2)
        y_3.append(y3)
        y_4.append(y4)
        y_5.append(y5)
        y_6.append(y6)
        y_7.append(y7)
        y_8.append(y8)
    

    既然已经分析好了,开始画图:

    a-七种情感维度的频数分布图

    #a-七种情感维度的频数分布图
    plt.ylabel("", fontproperties="SimSun") # 步骤一  (宋体)
    plt.title("七种情感维度的频数分布图", fontproperties="SimHei") #     (黑体)
    plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
    #乐好怒哀惧恶惊
    y_l=['乐','好','怒','哀','惧','恶','惊']
    yu=[sum(y_1),sum(y_2),sum(y_3),sum(y_4),sum(y_5),sum(y_6),sum(y_7)]
    plt.bar(y_l,yu, facecolor = 'blue', edgecolor = 'white')
    for a, b in zip(y_l, yu):
        plt.text(a, b, b, ha='center', va='bottom', fontsize=11)
    plt.savefig('a-七种情感维度的频数分布图.png')
    

    七种情感维度的频数分布图
    b-七种情感的时间变化图

    #b-七种情感的时间变化图
    #y_l=['乐','好','怒','哀','惧','恶','惊']
    fig = plt.figure(figsize=(10,6), facecolor = 'gray')
    plt.figure(figsize=(12,12))
    plt.subplot(331)
    plt.plot(x_,y_1)
    plt.title('乐')
    plt.subplot(332)
    plt.plot(x_,y_2)
    plt.title('好')
    plt.subplot(333)
    plt.plot(x_,y_3)
    plt.title('怒')
    plt.subplot(334)
    plt.plot(x_,y_4)
    plt.title('哀')
    plt.subplot(335)
    plt.plot(x_,y_5)
    plt.title('惧')
    plt.subplot(336)
    plt.plot(x_,y_6)
    plt.title('恶')
    plt.subplot(337)
    plt.plot(x_,y_7)
    plt.title('惊')
    plt.savefig('b-七种情感的时间变化图.png')
    
    

    七种情感的时间变化图.
    c-二元情感趋势图

    #c-二元情感趋势图
    yy_1=[]
    for i in range(len(x_)):
        #y_l=['乐','好','怒','哀','惧','恶','惊']
        yy_1.append(y_1[i]+y_2[i]-y_3[i]-y_4[i]-y_5[i]-y_6[i]-y_7[i])
    plt.plot(x_,yy_1)
    plt.title('二元情感趋势图')
    plt.savefig('c-二元情感趋势图.png')
    

    二元情感趋势图

    展开全文
  • B站弹幕数据分析与可视化, 自动化提取网站弹幕。输入网站地址即可提取。 弹幕数量 词云分析 情感分析 使用分析
  • 需要准备的环境:一个B站账号,需要先登录,否则不能查看历史弹幕记录联网的电脑和顺手的浏览器,我用的ChromePython3环境以及request模块,安装使用命令,换源比较快:pip3 install request -i ... 登录后打开需要爬取的视频...

    需要准备的环境:

    一个B站账号,需要先登录,否则不能查看历史弹幕记录

    联网的电脑和顺手的浏览器,我用的Chrome

    Python3环境以及request模块,安装使用命令,换源比较快:

    pip3 install request -i http://pypi.douban.com/simple

    爬取步骤: 登录后打开需要爬取的视频页面,打开开发者工具台,Chrome可以使用F12快捷键,选择network监听请求

    a1c7779c1cbf20d91c415de02260d36e.png

    点击查看历史弹幕,获取请求

    fdd85b90b27b12b4e4a169d9fe6e9498.png

    cd51155dfddf6eb83ca33573f4a5ba5c.png

    其中rolldate后面的数字表示该视频对应的弹幕号,返回的数据中timestamp表示弹幕日期,new表示数目

    5effaed33fc757b33b5f7dd6f80705f0.png

    在查看历史弹幕中任选一天,查看,会发出新的请求

    dmroll,时间戳,弹幕号,表示获取该日期的弹幕,1507564800 表示2017/10/10 0:0:0

    e6fad470ad1eea9c3a008cac1fc386f8.png

    55fd70a429b6285e0905bd8e4d53d784.png

    该请求返回xml数据

    c4ee97d63bec7fe8d7c013efef9d7537.png

    使用正则表达式获取所有弹幕消息,匹配模式

    '(.*?)'

    拼接字符串,将所有弹幕保存到本地文件即可

    with open('content.txt',mode='w+',encoding='utf8') as f: f.write(content)

    参考代码如下,将弹幕按照日期保存为单个文件...因为太多了...

    import requests

    import re

    import time

    """

    爬取哔哩哔哩视频弹幕信息

    """

    # 2043618 是视频的弹幕标号,这个地址会返回时间列表

    # https://www.bilibili.com/video/av1349282

    url = 'https://comment.bilibili.com/rolldate,2043618'

    # 获取弹幕的id 2043618

    video_id = url.split(',')[-1]

    print(video_id)

    # 获取json文件

    html = requests.get(url)

    # print(html.json())

    # 生成时间戳列表

    time_list = [i['timestamp'] for i in html.json()]

    # print(time_list)

    # 获取弹幕网址格式 'https://comment.bilibili.com/dmroll,弹幕号'

    # 弹幕内容,由于总弹幕量太大,将每个弹幕文件分别保存

    for i in time_list:

    content = ''

    j = 'https://comment.bilibili.com/dmroll,{0},{1}'.format(i,video_id)

    print(j)

    text = requests.get(j).text

    # 匹配弹幕内容

    res = re.findall('(.*?)',text)

    # 将时间戳转化为日期形式,需要把字符串转为整数

    timeArray = time.localtime(int(i))

    date_time = time.strftime("%Y-%m-%d %H:%M:%S",timeArray)

    print(date_time)

    content += date_time + '\n'

    for k in res:

    content += k + '\n'

    content += '\n'

    file_path = 'txt/{}.txt'.format(time.strftime("%Y_%m_%d",timeArray))

    print(file_path)

    with open(file_path,encoding='utf8') as f:

    f.write(content)

    最终效果

    e3540afa9d18d32a050f4750196dba7a.png

    b9674c7d08e43659120d266654d7d2c2.png

    之后可以 做一些分词生成词云或者进行情感分析,有时间在说吧....

    大家可以在下方给小编留言你学习的心得,也感谢你对编程小技巧的支持。

    展开全文
  • 弹幕情感分析.zip

    2019-05-25 09:13:44
    内含(弹幕抽取过程,情感词打分,中文各种词性分类,django框架运行等)。
  • 可以看我之前写的这篇文章:10行代码下载B站弹幕 代码 '''依赖模块 pip install requests ''' import re import requests url = input('请输入B站视频链接: ') res = requests.get(url) cid = re.findall(r'"cid":...


    成果展示

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    项目地址

    完整代码可在我的github中下载:https://github.com/XavierJiezou/python-danmu-analysis

    爬取弹幕

    可以看我之前写的这篇文章:10行代码下载B站弹幕

    下载代码

    # download.py
    '''依赖模块
    pip install requests
    '''
    import re
    import requests
    
    url = input('请输入B站视频链接: ')
    res = requests.get(url)
    cid = re.findall(r'"cid":(.*?),', res.text)[-1]
    url = f'https://comment.bilibili.com/{cid}.xml'
    res = requests.get(url)
    with open(f'{cid}.xml', 'wb') as f:
        f.write(res.content)
    

    样例输入

    B站番剧《花丸幼稚园》第六集视频播放地址:https://www.bilibili.com/bangumi/play/ep17617

    样例输出

    弹幕文件51816463.xml:https://comment.bilibili.com/51816463.xml

    数据处理

    下载弹幕文件51816463.xml后,我们打开看一下:

    <?xml version="1.0" encoding="UTF-8"?>
    <i>
        <chatserver>chat.bilibili.com</chatserver>
        <chatid>51816463</chatid>
        <mission>0</mission>
        <maxlimit>3000</maxlimit>
        <state>0</state>
        <real_name>0</real_name>
        <source>k-v</source>
        <d p="302.30800,1,25,16777215,1606932706,0,b105c2ee,41833218383544323">长颈鹿呢?还是大象呢?(</d>
        <d p="608.17000,1,25,16707842,1606926336,0,af4597df,41829878640672775">我也不想的,实在是太大了呀</d>
        <d p="249.95600,1,25,14811775,1606925877,0,af4597df,41829637765988357">真是深不可测啊</d>
        此处省略很多字
    </i>
    

    可以看到xml文件中d标签的text部分就是弹幕的文本,而d标签的p属性应该是弹幕的相关参数,共有8个,用逗号分隔。

    参数略解

    1. stime: 弹幕出现时间 (s)
    2. mode: 弹幕类型 (< 7 时为普通弹幕)
    3. size: 字号
    4. color: 文字颜色
    5. date: 发送时间戳
    6. pool: 弹幕池ID
    7. author: 发送者ID
    8. dbid: 数据库记录ID(单调递增)

    参数详解
    ① stime(float):弹幕出现时间,单位是秒;也就是在几秒出现弹幕。
    ② mode(int):弹幕类型,有8种;小于8为普通弹幕,8是高级弹幕。

    • 1~3:滚动弹幕
    • 4:底端弹幕
    • 6:顶端弹幕
    • 7:逆向弹幕
    • 8:高级弹幕

    ③ size(int):字号。

    • 12:非常小
    • 16:特小
    • 18:小
    • 25:中
    • 36:大
    • 45:很大
    • 64:特别大

    ④ color(int):文字颜色;十进制表示的颜色。
    ⑤ data(int):弹幕发送时间戳。也就是从基准时间1970-1-1 08:00:00开始到发送时间的秒数。
    ⑥ pool(int):弹幕池ID。

    • 0:普通池
    • 1:字幕池
    • 2:特殊池(高级弹幕专用)

    ⑦ author(str):发送者ID,用于"屏蔽此发送者的弹幕"的功能。
    ⑧ dbid(str):弹幕在数据库中的行ID,用于"历史弹幕"功能。

    了解弹幕的参数后,我们就将弹幕信息保存为danmus.csv文件:
    在这里插入图片描述

    # processing.py
    import re
    
    with open('51816463.xml', encoding='utf-8') as f:
        data = f.read()
    
    comments = re.findall('<d p="(.*?)">(.*?)</d>', data)
    # print(len(comments))  # 3000
    danmus = [','.join(item) for item in comments]
    headers = ['stime', 'mode', 'size', 'color', 'date', 'pool', 'author', 'dbid', 'text']
    headers = ','.join(headers)
    danmus.insert(0, headers)
    
    with open('danmus.csv', 'w', encoding='utf_8_sig') as f:
        f.writelines([line+'\n' for line in danmus])
    

    数据分析

    词频分析

    词云图在线查看:https://jsrun.net/uMwKp/embedded/all/light

    在这里插入图片描述

    # wordCloud.py
    '''依赖模块
    pip install jieba, pyecharts
    '''
    from pyecharts import options as opts
    from pyecharts.charts import WordCloud
    import jieba
    
    with open('danmus.csv', encoding='utf-8') as f:
        text = " ".join([line.split(',')[-1] for line in f.readlines()])
    
    words = jieba.cut(text)
    _dict = {}
    for word in words:
        if len(word) >= 2:
            _dict[word] = _dict.get(word, 0)+1
    items = list(_dict.items())
    items.sort(key=lambda x: x[1], reverse=True)
    
    c = (
        WordCloud()
        .add(
            "",
            items,
            word_size_range=[20, 120],
            textstyle_opts=opts.TextStyleOpts(font_family="cursive"),
        )
        .render("wordcloud.html")
    )
    

    情感分析

    饼状图在线查看:https://jsrun.net/6SwKp/embedded/all/light

    在这里插入图片描述

    由饼状图可知:3000条弹幕中,积极弹幕超过一半,中立弹幕有百分之三十几。

    当然,弹幕调侃内容居中,而且有很多梗,会对情感分析造成很大的障碍,举个栗子:

    >>> from snownlp import SnowNLP
    >>> s = SnowNLP('阿伟死了') 
    >>> s.sentiments
    0.1373666377744408
    

    "阿伟死了"因带有""字,所以被判别为消极情绪。但实际上,它反映的确是积极情绪,形容对看到可爱的事物时的激动心情。

    # emotionAnalysis.py
    '''依赖模块
    pip install snownlp, pyecharts
    '''
    from snownlp import SnowNLP
    from pyecharts import options as opts
    from pyecharts.charts import Pie
    
    with open('danmus.csv', encoding='utf-8') as f:
        text = [line.split(',')[-1] for line in f.readlines()[1:]]
    
    emotions = {
        'positive': 0,
        'negative': 0,
        'neutral': 0
    }
    for item in text:
        if SnowNLP(item).sentiments > 0.6:
            emotions['positive'] += 1
        elif SnowNLP(item).sentiments < 0.4:
            emotions['negative'] += 1
        else:
            emotions['neutral'] += 1
    print(emotions)
    
    
    c = (
        Pie()
        .add("", list(emotions.items()))
        .set_colors(["blue", "purple", "orange"])
        .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)"))
        .render("emotionAnalysis.html")
    )
    

    精彩片段

    折线图在线查看:https://jsrun.net/HSwKp/embedded/all/light

    在这里插入图片描述
    由折线图可知:第3分钟,第8、第9分钟,还有第13分钟分别是该视频的精彩片段。

    # highlights.py
    '''依赖模块
    pip install snownlp, pyecharts
    '''
    from pyecharts.commons.utils import JsCode
    from pyecharts.charts import Line
    from pyecharts.charts import Line, Grid
    import pyecharts.options as opts
    
    
    with open('danmus.csv', encoding='utf-8') as f:
        text = [float(line.split(',')[0]) for line in f.readlines()[1:]]
    
    
    text = sorted([int(item) for item in text])
    data = {}
    for item in text:
        item = int(item/60)
        data[item] = data.get(item, 0)+1
    
    
    x_data = list(data.keys())
    y_data = list(data.values())
    background_color_js = (
        "new echarts.graphic.LinearGradient(0, 0, 0, 1, "
        "[{offset: 0, color: '#c86589'}, {offset: 1, color: '#06a7ff'}], false)"
    )
    area_color_js = (
        "new echarts.graphic.LinearGradient(0, 0, 0, 1, "
        "[{offset: 0, color: '#eb64fb'}, {offset: 1, color: '#3fbbff0d'}], false)"
    )
    c = (
        Line(init_opts=opts.InitOpts(bg_color=JsCode(background_color_js)))
        .add_xaxis(xaxis_data=x_data)
        .add_yaxis(
            series_name="弹幕数量",
            y_axis=y_data,
            is_smooth=True,
            symbol="circle",
            symbol_size=6,
            linestyle_opts=opts.LineStyleOpts(color="#fff"),
            label_opts=opts.LabelOpts(is_show=True, position="top", color="white"),
            itemstyle_opts=opts.ItemStyleOpts(
                color="red", border_color="#fff", border_width=3
            ),
            tooltip_opts=opts.TooltipOpts(is_show=True),
            areastyle_opts=opts.AreaStyleOpts(
                color=JsCode(area_color_js), opacity=1),
            markpoint_opts=opts.MarkPointOpts(
                data=[opts.MarkPointItem(type_="max")])
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(
                title="",
                pos_bottom="5%",
                pos_left="center",
                title_textstyle_opts=opts.TextStyleOpts(
                    color="#fff", font_size=16),
            ),
            xaxis_opts=opts.AxisOpts(
                type_="category",
                boundary_gap=False,
                axislabel_opts=opts.LabelOpts(margin=30, color="#ffffff63"),
                axisline_opts=opts.AxisLineOpts(
                    linestyle_opts=opts.LineStyleOpts(width=2, color="#fff")
                ),
                axistick_opts=opts.AxisTickOpts(
                    is_show=True,
                    length=25,
                    linestyle_opts=opts.LineStyleOpts(color="#ffffff1f"),
                ),
                splitline_opts=opts.SplitLineOpts(
                    is_show=True, linestyle_opts=opts.LineStyleOpts(color="#ffffff1f")
                )
            ),
            yaxis_opts=opts.AxisOpts(
                type_="value",
                position="left",
                axislabel_opts=opts.LabelOpts(margin=20, color="#ffffff63"),
                axisline_opts=opts.AxisLineOpts(
                    linestyle_opts=opts.LineStyleOpts(width=2, color="#fff")
                ),
                axistick_opts=opts.AxisTickOpts(
                    is_show=True,
                    length=15,
                    linestyle_opts=opts.LineStyleOpts(color="#ffffff1f"),
                ),
                splitline_opts=opts.SplitLineOpts(
                    is_show=True, linestyle_opts=opts.LineStyleOpts(color="#ffffff1f")
                ),
            ),
            legend_opts=opts.LegendOpts(is_show=False),
            tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="line")
        )
        .render("highlights.html")
    )
    

    高能时刻

    更多时候,我们可能对精彩片段不太关注,而是想知道番剧的名场面出自几分几秒,即高能时刻

    # highEnergyMoment.py
    import re
    
    with open('danmus.csv', encoding='utf-8') as f:
        danmus = []
        for line in f.readlines()[1:]:
            time = int(float(line.split(',')[0]))
            text = line.split(',')[-1].replace('\n', '')
            danmus.append([time, text])
    
    danmus.sort(key=lambda x: x[0])
    dict1 = {}
    dict2 = {}
    control = True
    for item in danmus:
        if re.search('名场面(:|:)', item[1]):
            print(f'{int(item[0]/60)}m{item[0]%60}s {item[1]}')
            control = False
            break
        if '名场面' in item[1]:
            minute = int(item[0]/60)
            second = item[0] % 60
            dict1[minute] = dict1.get(minute, 0)+1
            dict2[minute] = dict2.get(minute, 0)+second
        else:
            pass
    if control:
        minute= max(dict1, key=dict1.get)
        second = round(dict2[minute]/dict1[minute])
        print(f'{minute}m{second}s 名场面')
    

    输出:9m29s 名场面:怀中抱妹鲨。我们去视频中看一下,9m29s确实是名场面:
    在这里插入图片描述

    福利情节

    字体颜色为黄色,也就是10进制颜色的值为16776960时,就是那种比较污的福利情节,同时为了防止异常,只有当该分钟内出现黄色弹幕的次数≥3时,才说明该分钟内是福利情节,并且输出该分钟内第一次出现黄色弹幕的秒数:

    02m15s 吼吼吼
    03m30s 什么玩意
    06m19s 真的有那么Q弹吗
    08m17s 憋死
    09m10s 前方万恶之源
    10m54s 噢噢噢噢
    11m02s 这就是平常心
    12m34s 这个我可以
    17m19s 因为你是钢筋混凝土直女
    18m06s 假面骑士ooo是你吗
    19m00s 警察叔叔就是这个人
    20m00s 金色传说的说。。。
    21m02s 嘿嘿嘿~
    
    # textColor.py
    with open('danmus.csv', encoding='utf-8') as f:
        danmus = []
        for line in f.readlines()[1:]:
            time = int(float(line.split(',')[0]))
            color = line.split(',')[3]
            text = line.split(',')[-1].replace('\n', '')
            danmus.append([time, color, text])
    
    danmus.sort(key=lambda x: x[0])
    dict1 = {}
    dict2 = {}
    for item in danmus:
        if item[1] == '16776960':
            minute = int(item[0]/60)
            second = item[0] % 60
            dict1[minute] = dict1.get(minute, 0)+1
            if dict2.get(minute) == None:
                dict2[minute] = f'{minute:0>2}m{second:0>2}s {item[2]}'
            else:
                pass
                
    for key, value in dict1.items():
        if value >= 3:
            print(dict2[key])
    
    展开全文
  • 《RunningMan》评论及弹幕情感分析

    千次阅读 热门讨论 2019-09-23 21:53:02
    《RunningMan》评论及弹幕情感分析,数据来源于b站,关键是自己实现情感得分的过程(由于篇幅问题,本文章没有放上相关代码)

    1数据说明

    1.1 数据说明

    本次实验用到的数据是《Running Man》视频的评论数据和弹幕数据。
    (1)评论数据格式:
    mid-uname-sex-ctime-rtime-review-like-rcount-date-time-week-score
    用户id-用户名-性别-评论时间戳-转化后的时间-评论内容-点赞数-回复数-评论日期-评论时间点-评论星期-评论情感得分
    在这里插入图片描述
    在这里插入图片描述
    (2)弹幕数据格式:
    second-ctime-rtime-danmu
    弹幕发在视频的第几秒-弹幕时间戳-转化后的时间-弹幕内容
    在这里插入图片描述

    1.2 数据来源

    本次实验所有数据均从bilibili爬取和处理得到。(b站的评论和弹幕数据比较容易爬取,这个也是网上搜到的思路)
    (1)来源
    评论数据来源于以下三个视频(17、18、19年RM节目的评论)
    https://www.bilibili.com/video/av12551207
    https://www.bilibili.com/video/av18089528
    https://www.bilibili.com/video/av40112794
    在这里插入图片描述
    弹幕数据来源于以下视频(10、11、12、17、18、19年RM节目合集,弹幕数据不用上述三个视频的弹幕原因是上述所有视频每一集弹幕数都是最大8000,不能通过弹幕数来比较每集节目)https://www.bilibili.com/video/av38441196

    在这里插入图片描述
    (2)获取方法

    ①评论获取 :16040条(2019/6/10获得)
    url= ‘https://api.bilibili.com/x/v2/reply?type=1&oid=18089528&pn=’ + str(i) + ‘&sort=0’ 关键是获取视频的oid,其实就是每个视频合集的av号,在上述1.2(1)来源中可见。可以爬取出用户id-用户名-评论时间戳-评论内容-点赞数-回复数
    在这里插入图片描述
    ②弹幕获取:252个视频弹幕,共457020条(2019/6/16获得)
    url= ‘https://comment.bilibili.com/’ + cid + '.xml’可以爬取出弹幕出现在视频第几秒-弹幕内容。关键是获取视频合集中每个视频的cid。
    在这里插入图片描述
    cid在合集页面源代码中,在爬取弹幕的视频合集中共252集(截止到2019/6/20)
    在这里插入图片描述

    2描述性统计

    2.1月评论数量

    在这里插入图片描述
    数据从2017年7月到2019年6月(6/16),可以看出2018年的各个月份评论数数是3年中最高的一年。另外每年的8月、1月都是本年度最多评论的两个月,其中2018年8月和2019年1月评论数高达1346和1357,推测是因为寒暑假和年假,导致观看学生或上班族人数增多。当前是6月下旬,所以推测接下来的7、8月份观看人数会出现增多趋势。

    2.2 星期评论数量

    在这里插入图片描述
    图中明显可以看出,一周中评论数最多的三天依次是周一、周二、周日。这是因为RM在韩国周日下午更新,在国内是周一更新,所以周一、周二的评论数是最多的。我本来认为做多的三天应该是周五、周六、周日,实际不符,所以我推测bilibili上RM的观众大部分是大学生和上班族这些年轻人,因为他们有时间能够及时追剧,而不用刻意等到周末。

    2.3 24小时时间段评论数量

    在这里插入图片描述
    在一天24小时中,评论数在1:00—7:00持续减少,而大多集中在11:00-14:00和19:00—1:00。显然大家观看的时间段集中在中午和晚上,最高一小时段中评论数超过1000。不过可能是年轻人的原因,很多评论都比较晚在22:00-1:00,还有少部分发生在凌晨。

    2.4 性别与时间段评论数量

    在这里插入图片描述
    在这里插入图片描述
    看整体发评论的用户性别,男女基本持平(女生稍多),大部分用户还是选择保密。但是从性别和24小时时间段来看,有一个有趣的现象:虽然凌晨发评论人数少,但是男生在0:00-7:00一直多于女生,说明熬夜人数中男生绝对多于女生。另外最突出的是女生在20:00—21:00的评论数,多达410,远远超过其它时间段(其它时间段都低于200)。

    2.5 用户发表评论数/被点赞数

    在这里插入图片描述
    几乎所有的用户发评论不会超过20条,这里选出15个发评论最多的用户。其中最多发评论的有114条,其次是49条,足以可见他们是RM的真爱粉。
    在这里插入图片描述
    几乎所有的用户评论累计点赞不会超过300,这里选出20个评论累计点赞最多的用户。其中最多的是7664,这是因为“一只南音呀”是RM视频合集的上传者(UP主),他的评论会被置顶,观众出于感谢会为其点赞;其次是6483、5514,这是他们用心评论的原因。

    2.6 评论词云图

    在这里插入图片描述
    由评论生成的词云来看,有意义的词中,“rm”、“弹幕”很明显,因此本次实验中也会注重对弹幕的分析。至于RM成员的名字,明显看出的有光洙、大神、全妹等,下面我也针对RM成员做了词频统计。

    2.7 每集弹幕数量

    在这里插入图片描述在这里插入图片描述
    252集节目中,弹幕平均1813条,最多8000条(bilibili限制),最少250条。从图中也可以看出,超过4000弹幕的节目很少,但是最新部分的节目弹幕整体很多,而之前的节目弹幕整体很少。推测观众更倾向于最新的节目,至于第一集节目为什么弹幕也很多,是因为许多人看到合集视频会从第一集看,并发弹幕表示对UP主的感谢,但是由于252集合集中想看最新的节目人数增多,同时从第1集坚持往下看的人数骤减,导致了这种情况。

    2.8 RM成员词频统计

    在这里插入图片描述
    利用jieba加载自定义词典(RM每个成员的名字、外号),计算词频。可以看出评论中提到最多的成员是宋智孝、李光洙、全昭旻,都超过了1000次,其中:①宋智孝以懵智、ACE、幸运女神这样的定位也非常成功,之前和Gary(原成员)的“周一情侣”,现在和金钟国的爱情线总是被人提及;
    ②李光洙是搞笑担当,被称为“综艺之神眷顾的男人”,节目中总是倒霉、臭手的形象;
    ③新成员全昭旻表现总是刻意出格而被冠上“全疯子”的外号,观众也经常因为其可爱、谈及她;
    ④与我设想不同,刘在石的提到次数并不是第一,因为刘在石是RM的灵魂人物;⑤评论中提及次数最少的是梁世灿,只有300多次,同样是新加入成员,梁世灿和全昭旻却是两个极端,全昭旻过于展现自己被粉丝接受或被批评,而梁世灿一直定位不明确,镜头很少,争议也很少。

    2.9 成员关系矩阵

    在这里插入图片描述
    在这里插入图片描述
    (X,Y)的值代表了X到Y的关联度,即X、Y同时出现占X的比例。图中可以看出三个比较突出的关系:宋智孝→金钟国、李光洙→池石镇、李光洙→HAHA。
    ①宋智孝和金钟国的爱情线吸引了许多CP粉,宋智孝→金钟国这条关系最强,达0.39,说明评论提到宋智孝时,39%的概率会提到金钟国;
    ②李光洙和池石镇、HAHA的关系比较强烈,因为三人组成了“背叛者联盟”
    在这里插入图片描述

    3情感分析

    其实这次作业的重点是要自己代码实现情感分析(并不是使用第三方情感得分库)

    3.1 评论情感分析

    在这里插入图片描述
    在16040条评论中,平均情感得分2.79,最低得分-60.36,最高得分152.47,说明还是喜爱RM的观众居多,另外也存在两个极端:特别喜爱和特别讨厌RM的观众。
    在这里插入图片描述
    选取大多数评论情感得分所在的区间【-20,20】,以2为间隔做出直方图。可以看出情感得分大致关于【0-2】这一范围呈钟型对称分布,而且这一范围评论数最多,超过4000条。其次是【-2,0】和【2,4】范围,评论均超过2500条。整体上可以说绝大部分的评论情感得分落在【-4,6】区间内。
    在这里插入图片描述
    按照月份做出平均情感得分图,可以看出,2017年的评论情感得分都很高,基本都保持在平均水平之上;而2018年的评论情感得分整体很低,基本低于平均分;而在2018年11月至今,情感得分明显有上升的趋势,说明今年以来的RM节目还是很受观众欢迎的。

    3.2 弹幕情感分析

    在这里插入图片描述在这里插入图片描述
    252集节目的弹幕情感得分平均得分1.51,最低0.51,最高2.87分,看来每集RM节目整体都受观众喜爱,但是喜爱程度还是有很大不同的。
    在这里插入图片描述
    选取弹幕数量大于2000的情感得分排名靠前的15集RM节目作为推荐
    在这里插入图片描述
    基于弹幕数量和弹幕情感,也可以分析了每一集节目随着时间线的变化情况,这里以E440.190224.伟大的钱争比赛(无嘉宾)这一期节目为例:
    在这里插入图片描述
    在这里插入图片描述
    从第一张图可以看出E440这一期整体的每分钟弹幕数和每分钟的弹幕情感得分;从第一张图中选取弹幕数量突增的时间段【40,60】,得到图二,可以看出当弹幕数量达到一段区域内的最大值时,弹幕情感得分也基本是小范围内的最高分,E440这期节目中选取四个片段42、48、51、56分钟,可以认为这四个视频片段是本期节目中最精彩的部分。由于只做了E440作为演示,对于其他集数不一定适用,但是但从弹幕数量来看,每集节目中弹幕数量骤增至顶峰的点必定是精彩片段。所以可以根据弹幕数量来识别精彩视频片段。(其实想搞个推荐的,但是发现没搞出来,尴尬。。)

    3.3 RM成员情感得分

    处理过程:
    (1)所有评论分词,保留含有成员名字的句子分词列表
    (2)找到成员名字位置,先向右再向左depth(本次实验我设置为2)范围内查找情感词,基础权重是1,如果找到了否定词或程度词,更新权重;如果找到了情感词,情感词得分×权重即为本次情感得分
    (3)遍历所有评论,计算每个成员的情感得分总值和次数,计算平均值
    在这里插入图片描述在这里插入图片描述
    处理过程我感觉是正确的,但是得到的结果我认为是错误的。首先结果显示情感得分最高的是全昭旻和梁世灿,都大于0.4分,但是两位都是17年加入的新成员,受到粉丝排斥和不公平辱骂是最多的,显然结果是不合理的。其次刘在石作为灵魂人物,评分应该不低,但结果显示为中等水平,只有0.19。至于宋智孝的评分应该比较合理,评分应该很高。总之这里的结果我认为不合理,原因可能是情感词典中的情感词评分不适用于RM。

    3.4 RM成员情感词词云

    在3.5过程中,只要将每个成员对应的情感值保存下来,即可分别做情感词词云。以下分别是刘在石、池石镇、金钟国、HAHA、宋智孝、李光洙、全昭旻、梁世灿。这些特征还是比较符合各个成员的。
    在这里插入图片描述在这里插入图片描述
    刘在石,很明显的“特辑”、“西装”;池石镇,年龄最大的成员,“针对”、“糊里糊涂”、“大叔”、“大哥”这些的确都是很明显的特点词。
    在这里插入图片描述在这里插入图片描述
    金钟国,作为能力者的人设,“欧巴”、“真英”(荧幕情侣之一)、“结婚”也都很符合。
    在这里插入图片描述在这里插入图片描述
    宋智孝,作为女神,“欧尼”、“表白”、“喜欢”、“姐姐”这些也很明显符合;李光洙,“心疼”、“欺负”(最倒霉最惨的)、“恋情”、“公开”(公开恋情后许多人的调侃)也很符合人设。
    在这里插入图片描述在这里插入图片描述
    最后是两位新人,全昭旻情感词是“喜欢”、“可爱”、“青蛙”等;梁世灿则是“新人”、“看不起”等等。

    • 节选自上学期的某课程作业(2019/6/20),瑕疵很多,做的很粗糙(懒得改了)
    • 参考了https://blog.csdn.net/csdnnews/article/details/84312510文章的思路(不过我的课程作业代码全是自己搞的哦)
    展开全文
  • 这篇文章语料来源于B站《后浪》弹幕,工具为python,着重讲述情感分析,顺便讲一下情绪分析。
  • 寄托情感的互联网文化符号——基于B站2017—2019年度弹幕的文本分析.pdf
  • 需要准备的环境:一个B站账号,需要先登录,否则不能查看历史弹幕记录联网的电脑和顺手的浏览器,我用的ChromePython3环境以及request模块,安装使用命令,换源比较快:pip3 install request -i ... 登录后打开需要爬取的视频...
  • 一、B站弹幕分析 B站弹幕数据存放在https://comment.bilibili.com/cid.xml中,其中cid是视频的cid号,获取需要爬取的视频的cid号的方法如下: 二、页面源代码 # -!- coding: utf-8 -!- import requests import re ...
  • 大家好,我是阿辰,今天来教大家如何实现『B站直播』弹幕实时分析思路:采集直播弹幕,然后通过情感分析,不同时间点的评论数,高频词统计一、采集直播弹幕首先在B站随意打开一个直播房间https:...
  • 基于爬取疫情期间新浪新闻评论、b站弹幕,运用NLP技术进行社会舆论分析的练习项目
  • bilibili弹幕分析,包含爬虫、词云分析、词频分析、情感分析、构建衍生指标,可视化 **** **主要依赖库** > selenium > pandas > lxml > json > requests > pyecharts > jieba > snownlp > wordcloud ...
  • b站视频弹幕.ipynb

    2020-08-23 15:58:28
    python爬取b站弹幕信息,并保存,绘制词云图,做情感分析,并将时间戳转换,通过弹幕发表时间,分析b站用户活跃时段。
  • 需要提前声明的是,截止写这篇文章时,冰冰视频显示有13.4w弹幕,但是B站通过接口暴露出的弹幕只有1000多条。(可以指定查询弹幕时间,但是基本每天暴露的数据都是相同的,如果全部采集再去重也还是1000条左右,故...
  • 关于《后浪》的B站弹幕分析总结(一)——爬取B站视频的上万条弹幕的方法 关于《后浪》的B站弹幕分析总结(二)——分词常用的词典、颜文字处理以及格式统一 关于《后浪》的B站弹幕分析总结(三)——怎么制作好看的...
  • b站视频弹幕分布.ipynb

    2020-08-23 16:00:00
    python爬取b站弹幕信息,并保存,绘制词云图,做情感分析,并将时间戳转换,通过弹幕发表时间,分析b站用户活跃时段。
  • 用此方法获取B站视频的XML弹幕 2.弹幕解析部分 将xml弹幕解析,并写入csv文件 代码部分: import xml.etree.ElementTree as ET import csv import time tree = ET.ElementTree(file='Test.xml') root = tree.get...
  • 本文的文字及图片来源于网络,仅供学习...B站作为一个弹幕视频网站,有着所谓的弹幕文化,那么接下来我们看看,一个视频中出现最多的弹幕是什么? 二、所用到得库 import re import csv import requests 三、知识点: 1.
  • 倒计时5天|Python&Stata数据分析课寒假工作坊观后感只有两个字昨天刷B站看到B站跨年晚会9.9分好评,抱着试试的态度,结果控制不住自己刷了两遍,书到用时方恨少,只想用...
  • 相信大部分人都看过了小破献给新一代的演讲(商业片)。习惯性地打开了微博和知乎,想看一下别人的看法,想知道我是不是有些颓废而与这个社会格格不入?当我打开了微博和知乎,我才发现《后浪》翻车了,原来我们都...
  • 原标题:用Python爬取B站视频弹幕via:菜J学Python众所周知,弹幕,即在网络上观看视频时弹出的评论性字幕。不知道大家看视频的时候会不会点开弹幕,于我而言,弹幕是视频内容的良好补充,是一个组织良好的评论序列...
  • 目录关于《后浪》的B站弹幕分析总结(二)——分词常用的词典、颜文字处理以及格式统一一、你需要知道的几个常用词典- **停用词典(停用词,颜文字,emoji)**- 否定词典,程度副词词典- 情感极性词典,多维情感词典...
  • 腾讯弹幕数据分析实战通用爬虫代码:令人心动的...人物被提及情感分析数据集:总结 通用爬虫代码: ''' Date: 2020-12-21 23:27:59 LastEditTime: 2020-12-22 16:36:43 ''' import requests import json import time
  • 爬取B站电视剧《风犬少年的天空》弹幕分析写在前面开始!新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 405
精华内容 162
关键字:

b站弹幕情感分析