先来个最终实现的效果:
输入一个bilibili的视频地址,生成这个视频弹幕的云图。
视频地址: https://www.bilibili.com/video/av47301018?from=search&seid=5397670291950820315
云图效果:
整体思路:
- 获取页面 html 数据
- 利用正则提取 cid , 组装出 cid 弹幕地址
- 获取 cid 地址相关的 xml 数据
- 利用BeautifulSoup 获取具体的弹幕数据
- 弹幕数据生成云图(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 标签,其实就是我们需要的弹幕数据。具体逻辑:
- 传入cid_url;
- 获取对应的 xml 内容;
- 通过BeautifulSoup 获取所有的 d 标签;
- 提取 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 进行云图的生成
可以展开的点:
- 提取其他网站的视频弹幕
- 生成有背景的云图
源码
#!/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")