手把手带你B站少量弹幕爬取并生成词云
最近准备爬虫大作业,突然想到爬取B站弹幕,于是马上行动。
一、先看看要用到的库
代码语言:javascript复制import requests
from bs4 import BeautifulSoup
import re
import pandas as pd
import time
import numpy as np
from PIL import Image
import jieba
import wordcloud
其中requests和bs4以及re是爬虫的主力军,而numpy、Image、jieba、wordcloud就是生成词云要用到的东西。pandas是便于格式化来输出文件是。
二、定义一些要用到的数据结构和请求头
代码语言:javascript复制headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36 FS"}
video_time=[]
abstime=[]
userid=[]
comment_content=[]
这里我们主要使用列表存储数据,请求头后面有两个函数需要用到,我们就将它放在外面吧。
三、寻找API
经过查询资料,我们知道类似于https://api.bilibili.com/x/v1/dm/list.so?oid=135354072这种链接可以获取到部分弹幕信息。然后我们来访问看一看。
是个xml文件,我们发现只需要获取这个oid参数就能获取某个视频的弹幕信息。
然后寻找视频对应的oid信息。
接着我们发现了https://api.bilibili.com/x/player/pagelist?bvid=BV1aJ411C7tb。这个链接就能获取视频链接的oid,就是这个cid
接着是获取bvid,这个就是视频链接中包含的信息。
就是这个链接https://www.bilibili.com/video/BV1aJ411C7tb。
四、获取cid
代码语言:javascript复制def get_cid(url):
data = requests.get(url=url,headers=headers)
data = data.json()
cid = data['data'][0]['cid']
return cid
我们发现获取cid的页面是个json文件,然后我们可以将直接取json文件中的cid的值。
五、获取弹幕信息
代码语言:javascript复制def get_info(url):
html = requests.get(url=url, headers=headers)
html.encoding = html.apparent_encoding
soup = BeautifulSoup(html.text,'lxml')
data_number=re.findall('d p="(.*?)">',html.text)
data_text=re.findall('">(.*?)</d>',html.text)
comment_content.extend(data_text)
for each_numbers in data_number:
each_numbers=each_numbers.split(',')
video_time.append(each_numbers[0])
abstime.append(time.strftime("%Y/%m/%d %H:%M:%S", time.localtime(int(each_numbers[4]))))
userid.append(each_numbers[6])
result={'用户id':userid,'评论时间':abstime,'视频位置(s)':video_time,'弹幕内容':comment_content}
results=pd.DataFrame(result)
final= results.drop_duplicates()
final.info()
final.to_excel('B站弹幕.xls')
这里我们还是获取那个xml文件,然后利用正则表达式获取xml中各个列的值,我们保存用户编号,评论时间,弹幕的视频位置,弹幕内容。然后保存到xls文件中。
六、分词
代码语言:javascript复制def getWord(text):
cut_txt = jieba.cut(text)
result = " ".join(cut_txt)
print(result[:30])
return result
这里介绍简单的利用jieba分词。然后将分词结果拼接成一个字符串。
七、生成词云
代码语言:javascript复制def setWordCloud():
pic = np.array(Image.open("./cat.jpg"))
stopwords = set(wordcloud.STOPWORDS)
stopwords.add("好")
font = r".妙笔生花.ttf"
wc = wordcloud.WordCloud(
font_path=font,
background_color="white",
max_words=1000,
mask=pic,
stopwords=stopwords,
max_font_size=30,
random_state=45
)
return wc
def getWordCloud(wc,result):
wc.generate(result)
wc.to_file("./wordcloud.jpg")
通过分词结果生成词云,然后导出图片。
八、主函数
代码语言:javascript复制def main():
url = "https://www.bilibili.com/video/BV1aJ411C7tb/?spm_id_from=autoNext"
cid_url = "https://api.bilibili.com/x/player/pagelist?bvid=" str(url[31:43]) "&jsonp=jsonp"
cid = get_cid(cid_url)
oid_url = 'https://api.bilibili.com/x/v1/dm/list.so?oid=' str(cid)
get_info(oid_url)
content = " ".join(comment_content)
word = getWord(content)
wc = setWordCloud()
getWordCloud(wc, word)
主函数比较简单,就是调用函数。在爬取弹幕方面,我们将网址中的信息进行提取和填充。在生成词云方面,我们先将弹幕信息拼接然后取分词,再来生成词云。
九、结语
本次爬虫主要是使用了基础的爬虫工具,如果要编写大型的爬虫,还是建议使用Scrapy。后面我会继续更新爬虫相关技术的文章,特别是使用Scrapy的教程。