過去一週突然有個很不錯的想法,想用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