之前,我参考了这篇文章,完成了第一次爬虫练习(爬取周杰伦新歌《Mojito》MV弹幕,看看粉丝们都说的些啥?)。
在完成第一次爬虫练习后,我开始思考,爬虫得到的数据,要如何进行数据分析呢?为此,我选择了另外一期视频,并对视频的弹幕进行数据分析。
爬虫部分,我根据公众号文章中给出的代码,结合自己的使用情况,成功获取了B站up主“花花与三猫CATLIVE”最新一期视频(BV1RK411n7EV)的弹幕列表,并将弹幕保存为txt文件。这个过程中,我还学习了正则表达式的使用。
数据分析部分,我想要分析的数据是:本期视频中哪只猫猫在弹幕中被提及的次数最多。
首先,up主家中一共有5只猫,每只猫都有着自己的名字和爱称。因此,数据分析的第一步,就是要列出所有猫猫的所有名字和别称,以统计所有提到这只猫的弹幕。这里列出五只猫的名字和部分昵称如下。
猫名 | 昵称 |
---|---|
中分 | 分分,分儿,分哥 |
李白 | 白老师,白白,呆比,呆逼 |
杜甫 | 甫甫,甫子 |
猪皮 | 猪猪 |
年糕 | 糕糕 |
将每只猫对应的关键词用列表保存,五个列表又形成一个总列表。进行比对时,使用双层循环遍历所有的关键词,并用变量c表示当前对应的是哪只猫的关键词。如果要添加新的关键词,直接在对应的列表中添加即可。
接下来使用正则表达式匹配相对应的弹幕。由于在爬虫过程中我们已经提取了弹幕内容,因此这里只需要考虑弹幕是否包含关键词即可。用'.*'+<关键词>+'.*'
表示弹幕中是否含有相应的关键词。判断弹幕内容与正则表达式是否匹配时,使用if re.match(p,i)!=None
,如果结果为True,则表示匹配成功,计数+1。为了以防一条弹幕中出现多个关键词,匹配成功后需要break跳出。最后使用**d的方法输出字典值。
import requests
import chardet
import re
#已经获取到cid:206064319
def getdata(cid):
url = "https://api.bilibili.com/x/v1/dm/list.so?oid=" + str(cid)
#获取网页数据
res = requests.get(url)
res.encoding = chardet.detect(res.content)
res = res.text
#接下来两句用来提取弹幕内容
#弹幕格式例:仿佛是我在玩
pattern = re.compile('(.*?)' )
data = pattern.findall(res)
return data
#保存弹幕
def save_to_file(data):
with open("dan_mu.txt", mode="w", encoding="utf-8") as f:
for i in data:
f.write(i)
f.write('\n')
#根据弹幕统计并输出
def count(data):
d = {
'c0': 0, 'c1': 0, 'c2': 0, 'c3': 0, 'c4': 0}
list1 = ['中分', '分分', '分哥', '分儿']
list2 = ['白老师', '李白', '白白', '呆比']
list3 = ['杜甫', '甫甫']
list4 = ['猪猪', '猪皮']
list5 = ['年糕', '糕糕']
list0 = [list1, list2, list3, list4, list5]
for i in data:
c = -1
for j in list0:
c += 1
for k in j:
s = '.*' + k + '.*'
p = re.compile(s)
if re.match(p, i) != None:
d['c' + str(c)] += 1
print('中分:{c0}\n白老师:{c1}\n甫甫:{c2}\n猪猪:{c3}\n糕糕:{c4}'.format(**d))
#如果已经保存了弹幕数据,可以用open()打开然后逐行读取
def count2(data):
dan_mu = open('dan_mu1.txt', 'r', encoding='utf-8')
d = {
'c0': 0, 'c1': 0, 'c2': 0, 'c3': 0, 'c4': 0}
list1 = ['中分', '分分', '分哥', '分儿']
list2 = ['白老师', '李白', '白白', '呆比']
list3 = ['杜甫', '甫甫']
list4 = ['猪猪', '猪皮']
list5 = ['年糕', '糕糕']
list0 = [list1, list2, list3, list4, list5]
while 1:
i = dan_mu.readline()
if not i:
break
c = -1
for j in list0:
c += 1
for k in j:
s = '.*' + k + '.*'
p = re.compile(s)
if re.match(p, i) != None:
d['c' + str(c)] += 1
break
print('中分:{c0}\n白老师:{c1}\n甫甫:{c2}\n猪猪:{c3}\n糕糕:{c4}'.format(**d))
data = getdata(206064319)
save_to_file(data)
count(data)