【爬虫+情感判定+Top10高频词+词云图】“谷爱凌”热门弹幕python舆情分析

一、背景介绍

最近几天,顾爱玲在冬奥会上获得了一枚宝贵的金牌,为中国队贡献了自己的荣誉。

[En]

In recent days, Gu Ailing won a precious gold medal in the Winter Olympic Games, contributing her honor to the Chinese team.

针对此热门事件,我用Python的爬虫和情感分析技术,针对小破站的弹幕数据,分析了众网友弹幕的舆论导向,下面我们来看一下,是如何实现的分析过程。

二、代码讲解-爬虫部分

2.1 分析弹幕接口

首先分析B站弹幕接口。

经分析,弹幕地址有两种:

[En]

After analysis, there are two kinds of on-screen comment addresses:

第一种:http://comment.bilibili.com/{cid}.xml
第二种:https://api.bilibili.com/x/v1/dm/list.so?oid={cid}
这两个回报的结果是一致的!但这并不是全部,这只是弹幕的一部分!

[En]

The results of these two returns are consistent! But it’s not all complete, it’s only part of the barrage!

以视频 https://www.bilibili.com/video/BV1YY41157dk 为例,查看网页源代码,可以找到对应的cid为 503862594,所以该视频对应的弹幕接口地址是:http://comment.bilibili.com/503862594.xml

【爬虫+情感判定+Top10高频词+词云图】“谷爱凌”热门弹幕python舆情分析

在这种情况下,很容易做到,开始玩代码吧!

[En]

In that case, it’s easy to do, start playing with the code!

2.2 讲解爬虫代码

首先,导入所需的库:

[En]

First, import the libraries you need:

import re  # 正则表达式提取文本
import requests  # 爬虫发送请求
from bs4 import BeautifulSoup as BS  # 爬虫解析页面
import time
import pandas as pd  # 存入csv文件
import os

然后,向视频地址发送请求,解析出cid号:

r1 = requests.get(url=v_url, headers=headers)
html1 = r1.text
cid = re.findall('cid=(.*?)&aid=', html1)[0]  # 获取视频对应的cid号
print('该视频的cid是:', cid)

根据cid号,拼出xml接口地址,并再次发送请求:

danmu_url = 'http://comment.bilibili.com/{}.xml'.format(cid)  # 弹幕地址
print('弹幕地址是:', danmu_url)
r2 = requests.get(danmu_url)

解析xml页面:标签的文本内容为弹幕,标签内p属性值(按逗号分隔)的第四个字段是时间戳:

soup = BS(html2, 'xml')
danmu_list = soup.find_all('d')
print('共爬取到{}条弹幕'.format(len(danmu_list)))
video_url_list = []  # 视频地址
danmu_url_list = []  # 弹幕地址
time_list = []  # 弹幕时间
text_list = []  # 弹幕内容
for d in danmu_list:
    data_split = d['p'].split(',')  # 按逗号分隔
    temp_time = time.localtime(int(data_split[4]))  # 转换时间格式
    danmu_time = time.strftime("%Y-%m-%d %H:%M:%S", temp_time)
    video_url_list.append(v_url)
    danmu_url_list.append(danmu_url)
    time_list.append(danmu_time)
    text_list.append(d.text)
    print('{}:{}'.format(danmu_time, d.text))

保存时应注意,为了避免多次写入csv标题头,像这样:

在这里,我写了一个处理逻辑。如果你看一下笔记,你应该能够理解:

[En]

Here, I have written a processing logic. If you look at the notes, you should be able to understand:

if os.path.exists(v_result_file):  # 如果文件存在,不需写入字段标题
    header = None
else:  # 如果文件不存在,说明是第一次新建文件,需写入字段标题
    header = ['视频地址', '弹幕地址', '弹幕时间', '弹幕内容']
df.to_csv(v_result_file, encoding='utf_8_sig', mode='a+', index=False, header=header)  # 数据保存到csv文件

三、代码讲解-情感分析部分

3.1 整体思路

针对情绪分析的需求,我主要做了三个步骤的分析:

[En]

In response to the needs of emotional analysis, I have mainly done three steps of analysis:

  1. 用SnowNLP给弹幕内容打标:积极、消极,并统计占比情况
  2. 用jieba.analyse分词,并统计top10高频词
  3. 用WordCloud绘制词云图

首先,导入csv数据,并做数据清洗工作,不再赘述。

接下来,正式进入情绪分析代码板块:

[En]

Next, officially enter the emotional analysis code section:

3.2 情感分析打标

对情绪分析得分进行计算、分类和评分,计算阳性/阴性比例。

[En]

The scores of emotion analysis were calculated, classified and marked, and the positive / negative proportion was calculated.

情感分析打标
def sentiment_analyse(v_cmt_list):
"""
    情感分析打分
    :param v_cmt_list: 需要处理的评论列表
    :return:
"""
    score_list = []  # 情感评分值
    tag_list = []  # 打标分类结果
    pos_count = 0  # 计数器-积极
    neg_count = 0  # 计数器-消极
    for comment in v_cmt_list:
        tag = ''
        sentiments_score = SnowNLP(comment).sentiments
        if sentiments_score < 0.3:
            tag = '&#x6D88;&#x6781;'
            neg_count += 1
        else:
            tag = '&#x79EF;&#x6781;'
            pos_count += 1
        score_list.append(sentiments_score)  # &#x5F97;&#x5206;&#x503C;
        tag_list.append(tag)  # &#x5224;&#x5B9A;&#x7ED3;&#x679C;
    print('&#x79EF;&#x6781;&#x8BC4;&#x4EF7;&#x5360;&#x6BD4;&#xFF1A;', round(pos_count / (pos_count + neg_count), 4))
    print('&#x6D88;&#x6781;&#x8BC4;&#x4EF7;&#x5360;&#x6BD4;&#xFF1A;', round(neg_count / (pos_count + neg_count), 4))
    df['&#x60C5;&#x611F;&#x5F97;&#x5206;'] = score_list
    df['&#x5206;&#x6790;&#x7ED3;&#x679C;'] = tag_list
    # &#x628A;&#x60C5;&#x611F;&#x5206;&#x6790;&#x7ED3;&#x679C;&#x4FDD;&#x5B58;&#x5230;excel&#x6587;&#x4EF6;
    df.to_excel('&#x8C37;&#x7231;&#x51CC;_&#x60C5;&#x611F;&#x8BC4;&#x5206;&#x7ED3;&#x679C;.xlsx', index=None)
    print('&#x60C5;&#x611F;&#x5206;&#x6790;&#x7ED3;&#x679C;&#x5DF2;&#x751F;&#x6210;&#xFF1A;&#x8C37;&#x7231;&#x51CC;_&#x60C5;&#x611F;&#x8BC4;&#x5206;&#x7ED3;&#x679C;.xlsx')

在这里,我将情绪得分小于0.3的人设置为负面,否则为积极。(这条分界线没有统一的标准。您可以根据数据分布和分析经验自行设置分界线。)

[En]

Here, I set the emotional score less than 0.3 as negative, otherwise as positive. (there is no uniform standard for this dividing line. You can set the dividing line yourself according to the data distribution and analysis experience.)

占比结果:

【爬虫+情感判定+Top10高频词+词云图】“谷爱凌”热门弹幕python舆情分析

阅卷结果:(最后两列分别为分数和阅卷结果)

[En]

Marking result: (the last two columns are the score and the marking result, respectively)

3.3 统计top10高频词

2&#x3001;&#x7528;jieba&#x7EDF;&#x8BA1;&#x5F39;&#x5E55;&#x4E2D;&#x7684;top10&#x9AD8;&#x9891;&#x8BCD;
keywords_top10 = jieba.analyse.extract_tags(v_cmt_str, withWeight=True, topK=10)
print('top10&#x5173;&#x952E;&#x8BCD;&#x53CA;&#x6743;&#x91CD;&#xFF1A;')
pprint(keywords_top10)

这里需要注意,在调用jieba.analyse.extract_tags函数时,要导入的是import jieba.analyse 而不是 import jieba
统计结果为:(分为10组关键词及其权重,权重按倒序排序)

【爬虫+情感判定+Top10高频词+词云图】“谷爱凌”热门弹幕python舆情分析

3.4 绘制词云图

注意别踩坑:
想要通过原始图片的形状生成词云图,原始图片一定要白色背景(实在没有的话,PS修图修一个吧),否则生成的是满屏词云!!

def make_wordcloud(v_str, v_stopwords, v_outfile):
"""
    &#x7ED8;&#x5236;&#x8BCD;&#x4E91;&#x56FE;
    :param v_str: &#x8F93;&#x5165;&#x5B57;&#x7B26;&#x4E32;
    :param v_stopwords: &#x505C;&#x7528;&#x8BCD;
    :param v_outfile: &#x8F93;&#x51FA;&#x6587;&#x4EF6;
    :return: None
"""
    print('&#x5F00;&#x59CB;&#x751F;&#x6210;&#x8BCD;&#x4E91;&#x56FE;&#xFF1A;{}'.format(v_outfile))
    try:
        stopwords = v_stopwords  # &#x505C;&#x7528;&#x8BCD;
        backgroud_Image = np.array(Image.open('&#x8C37;&#x7231;&#x51CC;&#x80CC;&#x666F;&#x56FE;.png'))  # &#x8BFB;&#x53D6;&#x80CC;&#x666F;&#x56FE;&#x7247;
        wc = WordCloud(
            background_color="white",  # &#x80CC;&#x666F;&#x989C;&#x8272;
            width=1500,  # &#x56FE;&#x5BBD;
            height=1200,  # &#x56FE;&#x9AD8;
            max_words=1000,  # &#x6700;&#x591A;&#x5B57;&#x6570;
            font_path='/System/Library/Fonts/SimHei.ttf',  # &#x5B57;&#x4F53;&#x6587;&#x4EF6;&#x8DEF;&#x5F84;&#xFF0C;&#x6839;&#x636E;&#x5B9E;&#x9645;&#x60C5;&#x51B5;(Mac)&#x66FF;&#x6362;
            # font_path="C:\Windows\Fonts\simhei.ttf",  # &#x5B57;&#x4F53;&#x6587;&#x4EF6;&#x8DEF;&#x5F84;&#xFF0C;&#x6839;&#x636E;&#x5B9E;&#x9645;&#x60C5;&#x51B5;(Windows)&#x66FF;&#x6362;
            stopwords=stopwords,  # &#x505C;&#x7528;&#x8BCD;
            mask=backgroud_Image,  # &#x80CC;&#x666F;&#x56FE;&#x7247;
        )
        jieba_text = " ".join(jieba.lcut(v_str))  # jieba&#x5206;&#x8BCD;
        wc.generate_from_text(jieba_text)  # &#x751F;&#x6210;&#x8BCD;&#x4E91;&#x56FE;
        wc.to_file(v_outfile)  # &#x4FDD;&#x5B58;&#x56FE;&#x7247;&#x6587;&#x4EF6;
        print('&#x8BCD;&#x4E91;&#x6587;&#x4EF6;&#x4FDD;&#x5B58;&#x6210;&#x529F;&#xFF1A;{}'.format(v_outfile))
    except Exception as e:
        print('make_wordcloud except: {}'.format(str(e)))

得到的词云图:

【爬虫+情感判定+Top10高频词+词云图】“谷爱凌”热门弹幕python舆情分析

和原始背景图对比:

【爬虫+情感判定+Top10高频词+词云图】“谷爱凌”热门弹幕python舆情分析

3.5 情感分析结论

  1. 打标结果中,积极评价占0.8871,远远大于消极评价!
  2. top10关键词统计结果中,”加油”、”厉害”、”天才”等好评词汇占据多数!
  3. 词云图中,”中国”、”好”、”厉害”、”卧槽”等好评词看上去更大(词频高)!

综上所述,经分析”谷爱凌”相关弹幕,得出结论:

众多网友对谷爱凌的评价都很高,也很喜欢她,毕竟不但年轻、颜值高、有才华,还能为祖国争得宝贵的荣誉!

致敬!!

四、同步讲解视频

上集:(爬虫采集)
https://www.zhihu.com/zvideo/1476299216318857217
下集:(情感分析)
https://www.zhihu.com/zvideo/1476300807759294464

五、附完整源码

附完整源码:点击这里完整源码

更多源码案例 -> 马哥python说

Original: https://www.cnblogs.com/mashukui/p/16244889.html
Author: 马哥python
Title: 【爬虫+情感判定+Top10高频词+词云图】“谷爱凌”热门弹幕python舆情分析

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/499642/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球