一、BeautifulSoup与lxml库的区别与比较
简单地概括二者的区别,在于操作的灵活性,本质上都是在解析html文档。
lxml是使用C语言完成XML处理的第三方库,因为C语言的特性,可以及其高速的运行。但是,同时操作起来非常灵活,也许不适用于初学者。
BeautifulSoup,相反地,尽管操作没有lxml那么灵活,但是操作简单易懂。内部有4个解析器(常用为lxml解析器),可以根据使用目的进行替换。
二、XML是什么,以及B站弹幕的位置
XML,可扩展标记语言,是对超文本标记语言的补充。
它和超文本标记语言为不同的目的而设计:
1,它被设计用来传输和存储数据,其焦点是数据的内容。
2,超文本标记语言被设计用来显示数据,其焦点是数据的外观。
超文本标记语言旨在显示信息,而它旨在传输信息。
对它最好的描述是:它是独立于软件和硬件的信息传输工具。
因此弹幕作为实时数据,必然会存储在XML文件中。自然地,B站视频上的弹幕都有一个对应的XML文件,于是我们可以通过解析XML文件获取到B站视频的弹幕。
那么它在哪里呢?
打开heartbeat这个文件,在这里能够看到aid即为视频号(能在url找到它),cid即是存储弹幕的编号。
在访问时,按照这个进行访问就ok了。
http://comment.bilibili.com/(cid).xml
那么在这里就是http://comment.bilibili.com/77853722.xml
三、利用Beautifulsoup或者lxml库进行弹幕信息的爬取,并通过pandas存储为csv文件
以上是访问xml文件的结果,发现了弹幕都是在
Beautifulsoup的做法:
import requests
from bs4 import BeautifulSoup
url = 'https://comment.bilibili.com/69082679.xml'
response = requests.get(url)
html = response.content
html_doc = str(html, 'utf-8')
soup = BeautifulSoup(html_doc, 'lxml')
results = soup.find_all('d')
contents = [ x.text for x in results ]
lxml的做法:
import requests
import lxml.html
url = 'https://comment.bilibili.com/77853722.xml'
response = requests.get(url)
html = lxml.html.fromstring(response.content)
print(type(html)) #在这里返回
h1 = html.cssselect('d')
print(type(h1)) #在这里返回
contents = [x.text for x in h1]
再利用pandas的Dataframe进行csv文件的输出:
import pandas as pd
table_dict = {"contents":contents}
df = pd.DataFrame(table_dict)
df.to_csv("bibi.csv", encoding = 'utf-8')
结果大致为:
四、使用jieba、pyecharts进行词云分析
首先利用jieba库进行单词的获取
import jieba
def get_word(file, stop_words):
df = pd.read_csv(file, encoding = 'utf-8')
df.head() #确认数据有没有进来
df.dropna(inplace = True) #清除缺失值
content = df.contents.values.tolist() #将contents一列转换为list列表
segment = list()
#jieba分词
for line in content:
try:
segs = jieba.cut_for_search(line)
segs = [v for v in segs if not str(v).isdigit()]
for seg in segs:
if len(seg) > 1 and seg != '\r\n':
segment.append(seg)
except:
print(line)
continue
words_df = pd.DataFrame({'segment': segment})
print(words_df)
stopwords = pd.read_csv(stop_words, index_col=False, quoting=3, sep="\t", names=['stopword'], encoding='utf-8')
# 安装关键字groupby分组统计词频,并按照计数降序排序
words_stat = words_df.groupby(by=['segment'])['segment'].agg({"count": np.size})
words_stat = words_stat.reset_index().sort_values(by=["count"], ascending=False)
# 分组之后去掉停用词
words_stat = words_stat[~words_stat.segment.isin(stopwords.stopword)]
print(words_stat)
return words_stat
这段代码完全引用了这位大神的代码https://github.com/sujeek/comment_bilibili,其中包含停用词的txt文件。希望大神多多包涵。
再利用pyecharts中Wordcloud库
from pyecharts import WordCloud
wordcloud = WordCloud(width = 1300, height = 620)
wordcloud.add("", words_stat['segment'], words_stat["count"],word_size_range=[20,100])
wordcloud.render('nidaibalema.html')
五、输出结果
使用pyecharts库输出的词云具有动态效果,非常赞。
但是从图中也可以看出项“哈哈哈”和“哈哈哈哈”并没有归为统一的词。算法还有待改进,今后考虑出一篇专门的jieba学习帖。
从图中可以得到,这集确实高能,awsl最近真的好火啊。。