【Python】获取视频弹幕并生成词云

目录

  • 一、摘要
  • 二、获取目标视频cid
  • 三、获取视频弹幕xml文件
  • 四、处理弹幕文件
  • 五、生成词云
  • 六、完整参考代码

一、摘要

就是那个大家都用的弹幕视频网站,不写名字了,写了老是不能通过。

获取视频的弹幕文件(xml),并生成如图所示的词云:


用到的技术有:

  1. 使用requests模块请求弹幕的xml文件;
  2. 使用xpath解析,获取xml文件中的字幕;
  3. 使用jieba对弹幕内容进行分词;
  4. 使用 wordcloud生成词云。

二、获取目标视频cid

这个网站的视频以前使用AV号来唯一标记一个视频,后来改为BV号(打开移动端APP在视频的详情处即可看到),通过这两种标识号码可以直接搜索到对应的视频。

此外,一个视频还可以用cid、aid、bvid等来标识,本文使用cid来构造HTTP请求。获取视频cid的方法之一是:

  1. 打开视频播放页面,(F12)检查页面;
  2. 选择network选项,并搜索cid;
  3. 点击其中一个结果,即可在payload选项下看到cid信息。
    【Python】获取视频弹幕并生成词云_第1张图片

当然也可以点击视频的统计信息,下载统计信息文件,然后搜索cid。或者在程序中实现通过URL获取cid,方式不唯一。

三、获取视频弹幕xml文件

请求弹幕文件的方法有两种(截止今天,我用到的):

在这里插入图片描述

其中将cid号换成目标视频的cid即可。

直接在地址栏输入上面的地址即可预览视频的xml文件,可见弹幕内容都在

标签下面
【Python】获取视频弹幕并生成词云_第2张图片
本文使用requests模块来获取该文件,并以cid号命名保存。

  # 下载视频弹幕的xml文件
    def dm_xml(self):
        url = 'https://comment.bilibili.com/' + self.cid+ '.xml'
        try:
            response = requests.get(url)
        except Exception as e:
            print('获取xml内容失败,%s' % e)
            return False
        else:
            if response.status_code == 200:
                with open(f'{self.cid}.xml','wb') as f:
                    f.write(response.content)
                    print('成功下载弹幕xml文件')
                    return True
            else:
                return False

四、处理弹幕文件

下载xml后,需要进行如下操作,得到wordcloud的标准输入(string):

  1. 对每个

    标签内的内容进行解析,并将其拼接成字符串;

  2. 在使用jieba进行分词,将弹幕切分为一个个词语;
  3. 去掉停用词,比如啊、尽管、就是、因为这样的词语,它们大量出现,但却不能反映弹幕的真实情感。
    # 将xml文件中的文本提取出来,去掉停用词,分词
    def get_dm_txt(self):
        # 读取停用词,可以根据结果添加停用词
        with open("ChineseStopWords.txt", "r", encoding="utf-8") as fp:
            stopwords = [s.rstrip() for s in fp.readlines()]
        self.dm_xml()
        time.sleep(5)
        html = etree.parse(f'{self.cid}.xml', etree.HTMLParser())
        # xpath解析,获取当前所有的d标签下的所有文本内容
        text = html.xpath('//d//text()')
        # 列表拼接成字符串
        text = ''.join(text)
        text = jieba.lcut(text)
        words = []
        for w in text:
            if w not in stopwords:
                words.append(w)
        # 注意此处有空格
        words = ' '.join(words)
        return words

五、生成词云

使用wordcloud的generate()函数即可生成词云,再使用matplotlib显示即可。

此处要注意的一些参数有:

  1. collocations,此参数设置为False可以保证每个词云只出现一次;
  2. scale,缩放比例,该值越大,图像越清晰,但不宜太大,会导致加载变慢。
    # 生成词云
    def wd(self):
        # collocations用于去掉重复词语;scale值越大清晰度越高,但太大加载会变慢
        wd = WordCloud(font_path='simhei.ttf',colormap="spring",width=800,height=400,
                       collocations=False,scale=5).generate(self.get_dm_txt())
        # 保存图片
        wd.to_file(f'{self.cid}.PNG')
        plt.imshow(wd, interpolation='bilinear')
        plt.axis("off")
        plt.show()

六、完整参考代码

最后修改日期 2023-1-9 20:57

读者可自行修改:如直接使用url下载,生成评论词云,设置词云形状等。

# -*- coding = utf-8 -*-
# @TIME :     2023-1-9 上午 12:24
# @Author :   CQUPTLei
# @File :     Bilibili_bullet_screen.py
# @Software : PyCharm
# @Abstract : 获取视频弹幕并做成词云
"""
截止本代码创作日,可以获取弹幕xml文件的请求方url有:
(url里面的一串数字是视频的cid)
    https://comment.bilibili.com/176244239.xml
    https://api.bilibili.com/x/v1/dm/list.so?oid=413440316
cid的获取:
    在相应的视频播放也,F12检查,network选项下搜索cid即可。
    Headers里面的RequURL里面就包含有cid
    或者Payload下也有,aid,cid,bvid之类的都有
有空了改进一下,直接通过视频URL湖区cid
"""
import time
import jieba
import requests
from lxml import etree
from wordcloud import WordCloud
import matplotlib.pyplot as plt

class Get_Bilibili_danmu(object):
    # 定义对象属性
    def __init__(self, cid):
        self.cid = cid

    # 下载视频弹幕的xml文件
    def dm_xml(self):
        url = 'https://comment.bilibili.com/' + self.cid+ '.xml'
        try:
            response = requests.get(url)
        except Exception as e:
            print('获取xml内容失败,%s' % e)
            return False
        else:
            if response.status_code == 200:
                with open(f'{self.cid}.xml','wb') as f:
                    f.write(response.content)
                    print('成功下载弹幕xml文件')
                    return True
            else:
                return False

    # 将xml文件中的文本提取出来,去掉停用词,分词
    def get_dm_txt(self):
        # 读取停用词,可以根据结果添加停用词
        with open("ChineseStopWords.txt", "r", encoding="utf-8") as fp:
            stopwords = [s.rstrip() for s in fp.readlines()]
        self.dm_xml()
        time.sleep(5)
        html = etree.parse(f'{self.cid}.xml', etree.HTMLParser())
        # xpath解析,获取当前所有的d标签下的所有文本内容
        text = html.xpath('//d//text()')
        # 列表拼接成字符串
        text = ''.join(text)
        text = jieba.lcut(text)
        words = []
        for w in text:
            if w not in stopwords:
                words.append(w)
        # 注意此处有空格
        words = ' '.join(words)
        return words

    # 生成词云
    def wd(self):
        # collocations用于去掉重复词语;scale值越大清晰度越高,但太大加载会变慢
        wd = WordCloud(font_path='simhei.ttf',colormap="spring",width=800,height=400,
                       collocations=False,scale=5).generate(self.get_dm_txt())
        # 保存图片
        wd.to_file(f'{self.cid}.PNG')
        plt.imshow(wd, interpolation='bilinear')
        plt.axis("off")
        plt.show()

if __name__ == '__main__':
    test_dm = Get_Bilibili_danmu('176244239')
    test_dm.wd()

你可能感兴趣的:(Python数据分析,python,开发语言,人工智能)