zl程序教程

您现在的位置是:首页 >  其他

当前栏目

手把手带你B站少量弹幕爬取并生成词云

2023-03-20 15:41:00 时间

手把手带你B站少量弹幕爬取并生成词云

最近准备爬虫大作业,突然想到爬取B站弹幕,于是马上行动。

一、先看看要用到的库

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是便于格式化来输出文件是。

二、定义一些要用到的数据结构和请求头

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

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的值。

五、获取弹幕信息

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文件中。

六、分词

def getWord(text):
    cut_txt = jieba.cut(text)
    result = " ".join(cut_txt)
    print(result[:30])
    return result

这里介绍简单的利用jieba分词。然后将分词结果拼接成一个字符串。

七、生成词云

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")

通过分词结果生成词云,然后导出图片。

八、主函数

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的教程。