[彈幕詞雲姬]硬核b站up主一週擼出來的小工具,根據b站彈幕生成詞雲(一)

過去一週突然有個很不錯的想法,想用b站的彈幕來生成一個詞雲的效果。於是辛苦奮戰一週,大概花了十個小時左右,整出了這個全新的小工具——《詞雲彈幕姬》訪問地址http://danmu.xiezuoguan.cn/
參考我上傳的b站視頻

「彈幕詞雲姬」硬核up主花費一週開發了一款根據彈幕生成詞雲的工具

先給大家看下效果,主要界面如下,上面是兩個輸入框來輸入av號和cid號來定位視頻。中間是選擇背景圖,下方是最近大家提交過的內容。

在這裏插入圖片描述
在這裏插入圖片描述
這個是輸入av號點查詢的效果。查詢成功會提示解析成功並自動帶出cid號(什麼是cid號下面會講)
在這裏插入圖片描述

這個是詞雲最終生成的效果圖
在這裏插入圖片描述
在這裏插入圖片描述

演示完成後我們開始簡單講技術部分
後端開發:
核心內容就三部分,第一部分如何獲取彈幕信息,第二部分如何分詞,第三部分如何生成詞雲。

第一部分獲取彈幕:

這個是百度一下就有前人的經驗,這個玩意兒是從cid號查到的,訪問’http://comment.bilibili.com/’+str(cid)+’.xml’就是獲取的彈幕信息了。那cid號又是從哪裏來的呢?
訪問一個視頻後,加載的html裏直接ctrl+F搜索cid就可以了。但是我們是學技術的嘛,所要用正則表達式匹配出來,函數代碼如下:

#根據av號獲取cid
def get_cid_from_av(av):
    url = 'http://www.bilibili.com/video/av'+str(av)
    #print(url)
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.103 Safari/537.36'}
    response = requests.get(url=url, headers=headers)
    response.encoding = 'utf-8'
    html = response.text
    #print(html)
    #用try防止有些av號沒視頻
    try:
        soup = BeautifulSoup(html, 'lxml')
        #視頻名
        title = soup.select('meta[name="title"]')[0]['content']
        #投稿人
        author = soup.select('meta[name="author"]')[0]['content']
        #彈幕的網站代碼
        danmu_id = re.findall(r'cid=(\d+)&', html)[0]
        #print(title, author)
        #return danmu_id
        #寫到文件裏
        write_last_commit(title, author)
        return {'status': 'ok','title': title, 'author': author, 'cid': danmu_id}
    except:
        print('視頻不見了喲')
    return {'status': 'no'}

然後有了cid之後獲取彈幕,通過jieba這個python庫進行分詞

#獲取彈幕
def get_danmu(cid):
    url = 'http://comment.bilibili.com/'+str(cid)+'.xml'
    # print(url)
    req = requests.get(url)
    html = req.content
    html_doc=str(html,'utf-8')   #修改成utf-8
    
    #解析
    soup = BeautifulSoup(html_doc,"lxml")
    
    results = soup.find_all('d')
    
    contents = [x.text for x in results]
    # print(contents)
    return contents

第一部分完成

第二部分分詞

#彈幕分詞
def danmu_cut(data):
    word_frequency = dict()
    #獲取停止詞
    stop_word = []
    #路徑問題
    module_path = os.path.abspath(os.curdir)
    file_path = os.path.join(module_path,"stopWordList.txt")
    with open(file_path,'r', encoding='UTF-8' ) as f:
        for line in f.readlines():
            stop_word.append(line.strip())
    #分詞
    words = jieba.cut(data)
    #統計詞頻
    for word in words:
        if word not in stop_word:
            word_frequency[word] = word_frequency.get(word, 0) + 1
    return word_frequency

最後第三部分生成詞雲

這塊用到wordcloud庫,百度也有很多寫好的東西,我們拿過來改一改就可以用了。

#詞雲用於web
def draw_wordcloud_for_web(words_dict,cid,mask_pic):
    #背景圖片
    #絕對路徑問題
    module_path = os.path.abspath(os.curdir)
    #filename = module_path + "\\bilibili\\"+mask_pic
    input_file = os.path.join(module_path,'mask_pic',mask_pic)
    mask = np.array(Image.open(input_file))
    font_file = os.path.join(module_path,'simhei.ttf')
    print(font_file)
    wc = WordCloud(
        font_path=font_file,  # 設置字體格式
        mask=mask,
        max_words=200,
        max_font_size=60,
        min_font_size=10,
        random_state=50,
    )
    wc.generate_from_frequencies(words_dict)
    image_colors = ImageColorGenerator(mask)
    wc.recolor(color_func=image_colors)
    # return wc.to_image()
    #輸出的文件名
    out_file_name = str(cid)+'.jpg'
    out_file = os.path.join(module_path,'out_put',out_file_name)
    wc.to_file(out_file)
    return out_file

至此,python的腳本部分已經完成(實不相瞞,此部分就花了我兩個小時不到)
下一節將如何用fastapi將這些通過http server 對外提供成api服務
再下一節簡單講講畫前端vue

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章