有趣的Python —— bilibili弹幕爬取 + 云图生成


先来个最终实现的效果:

输入一个bilibili的视频地址,生成这个视频弹幕的云图。

视频地址: https://www.bilibili.com/video/av47301018?from=search&seid=5397670291950820315

云图效果:

在这里插入图片描述


整体思路:

  1. 获取页面 html 数据
  2. 利用正则提取 cid , 组装出 cid 弹幕地址
  3. 获取 cid 地址相关的 xml 数据
  4. 利用BeautifulSoup 获取具体的弹幕数据
  5. 弹幕数据生成云图(WordCloud)

涉及库的安装:

pip install beautifulsoup4 wordcloud

1. 分析网页数据,提取cid

通过 chorme 打开视频地址。

查看网页源代码(在网页上右键可以出来菜单)

搜索一下 “cid”:

会发下下面的样子:

在这里插入图片描述

发现第一个匹配的cid 数据,就是这个视频的 cid , 也就是我们需要的 cid code

这一步比较简单,其实就是分析出 cid 的code. 组装成 弹幕下载的地址。

cid 获取弹幕的规则是 : https://comment.bilibili.com/{}.xml ,{}替换对应cid code

这一步的代码很简单:

    def get_cid_url(self, org_url):
        """
        先获取链接的 html 文件
        通过正则匹配出 cid code
        生成 弹幕链接 放回
        :param org_url: 视频地址
        :return: 弹幕地址
        """
        html_data = self.get_url_data(org_url)
        cid = re.findall(r"\"cid\":([\d]+),", str(html_data))[0]
        return "https://comment.bilibili.com/{}.xml".format(cid)

2. cid 数据提取弹幕

首先来个弹幕地址,打开之后是怎么样的:

地址: https://comment.bilibili.com/82840963.xml

在这里插入图片描述

这个其实比较简单,那些 d 标签,其实就是我们需要的弹幕数据。具体逻辑:

  1. 传入cid_url;
  2. 获取对应的 xml 内容;
  3. 通过BeautifulSoup 获取所有的 d 标签;
  4. 提取 d 标签里面的数据 ,并且组装成为一个字符串用逗号分隔。

这一步的代码:

    def get_all_tags(self, cid_url):
        """
        获取弹幕  xml 文件
        利用 beautifulSoup 获取所有弹幕文案
        :param cid_url: 弹幕获取url
        :return: 所有弹幕list
        """
        xml_data = self.get_url_data(cid_url) 
        soup = BeautifulSoup(xml_data, features="xml")
        all_data=""
        for item in soup.find_all("d"):
            all_data = all_data + item.string + ","
        return all_data
        

3. 弹幕数据云图生成

获取到弹幕的数据之后,就是最后一个步骤了,生成云图。

这一步使用的是 WordCloud 库进行云图的生成,下面是新建一个 WordCloud 实体:

wordcloud = WordCloud(font_path=“STXINGKA.TTF”
,background_color=“white”
, width= 800
, height=400
, max_words=100)

参数解析:
font_path:这个是中文字体路径,这里直接放在和根目录,如果是中文的云图,必须加上这个字体的设置,不然出现乱码的情况
background_color:云图的背景颜色
width,height :云图的宽高设置
max_words : 最大展示的词数量

还有一个参数,这里讲一下,就是 mask 这个参数,是可以设置图片背景的,就是生成的云图,是根据你的图片来进行的。

最后,新建了WordCloud, 传入我们前两步得到的 弹幕数据,就可以获取到一张有趣的云图了。

    def create_could_pic(self, tags):
        wordcloud = WordCloud(font_path="STXINGKA.TTF"
                              ,background_color="white"
                              , width= 800
                              , height=400
                              , max_words=100)
        wordcloud.generate(tags)
        image = wordcloud.to_image()

        image.show()

总结

这个爬取的思路比较简单。重点在于,灵活运用库的力量。

re 进行正则的匹配
requests 进行网页数据的获取
BeautifulSoup 进行数据的提取
WordCloud 进行云图的生成

可以展开的点:

  1. 提取其他网站的视频弹幕
  2. 生成有背景的云图

源码

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

__author__ = 'Weijian Xuan'

import re
from bs4 import BeautifulSoup
import requests
from wordcloud import WordCloud

class Bilibili(object) :

    @staticmethod
    def get_url_data(url):
        headers = {
            "User-Agent":"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Mobile Safari/537.36"
        }
        response = requests.get(url = url, headers = headers)
        return response.content.decode()

    def get_cid_url(self, org_url):
        """
        先获取链接的 html 文件
        通过正则匹配出 cid code
        生成 弹幕链接 放回
        :param org_url: 视频地址
        :return: 弹幕地址
        """
        html_data = self.get_url_data(org_url)
        cid = re.findall(r"\"cid\":([\d]+),", str(html_data))[0]
        return "https://comment.bilibili.com/{}.xml".format(cid)

    def get_all_tags(self, cid_url):
        """
        获取弹幕  xml 文件
        利用 beautifulSoup 获取所有弹幕文案
        :param cid_url: 弹幕获取url
        :return: 所有弹幕list
        """
        xml_data = self.get_url_data(cid_url)
        soup = BeautifulSoup(xml_data, features="xml")
        all_data=""
        for item in soup.find_all("d"):
            all_data = all_data + item.string + ","
        return all_data

    def create_could_pic(self, tags):
        wordcloud = WordCloud(font_path="STXINGKA.TTF"
                              ,background_color="white"
                              , width= 800
                              , height=400
                              , max_words=100)
        wordcloud.generate(tags)
        image = wordcloud.to_image()

        image.show()

    def run(self, url):
        tags = self.get_all_tags(self.get_cid_url(url))
        self.create_could_pic(tags)



if __name__ == "__main__":
    bibi = Bilibili()
    bibi.run("https://www.bilibili.com/video/av47301018?from=search&seid=5323472189377090516")




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章