原創不易,本文禁止抄襲,轉載請附上鏈接,違權必究forever!
目錄
- 一、EDG奪冠資訊
- 二、實戰目標
- 2.1 網路爬蟲
- 2.2 資料可視化(詞云圖)
- 2.3 自然語言處理(情感分析)
- 三、bilibili介面分析
- 四、編碼
- 4.1 爬取資料
- 4.2 資料可視化(詞云圖)
- 五、自然語言處理(NLP)
- 5.1 資料匯入
- 5.2 資料預處理
- 5.3 情感分析
- 5.4 情感分析直方圖
- 5.5 關鍵詞提取
- 5.6 積極彈幕與消極彈幕
- 5.7 餅圖分析
- 5.8 消極彈幕分析
- 六、總結
- 七、完整專案下載
- 八、作者Info
一、EDG奪冠資訊
11月6日,在英雄聯盟總決賽中,EDG戰隊以3:2戰勝韓國隊,獲得2021年英雄聯盟全球總決賽冠軍,這個比賽在全網各大平臺也是備受矚目:
1、微博熱搜第一名,截止2021-11-10已有億級觀看量,微博粉絲數到達638.4萬

2、嗶哩嗶哩已有幾億人氣,總彈幕有22.3萬,全站排行榜最高第2名,B站粉絲已有219.9萬


3、騰訊、愛奇藝、優酷等視頻平臺800萬人看過
4、虎牙等直播平臺熱度也是居高不下
5、央視新聞也發微博慶祝EDG奪冠


既然比賽熱度這么高,那么本次我們就以bilibili為基準,通過采集EDG奪冠比賽視頻在嗶哩嗶哩的3萬條彈幕資料,再通過Python來分析進而感受粉絲的熱情
二、實戰目標
2.1 網路爬蟲
利用爬蟲技術抓取EDG戰隊在B站奪冠比賽視頻的3萬條彈幕資料

2.2 資料可視化(詞云圖)
通過jieba、numpy等Python庫對抓取來的彈幕資料進行分析并且可視化


2.3 自然語言處理(情感分析)
利用pandas+自然語言處理(NLP)等對EDG奪冠比賽視頻的3萬條彈幕資料進行情感分析,根據分析結果得出一些結論



三、bilibili介面分析
首先進入EDG奪冠比賽視頻URL:
https://www.bilibili.com/video/BV1EP4y1j7kV?p=1
嗶哩嗶哩已為大家整理好了EDG比賽視頻,從開幕式到奪冠時刻,共有7個視頻

嗶哩嗶哩彈幕資料介面:
http://api.bilibili.com/x/v1/dm/list.so?oid=XXX
這個介面就是B站彈幕資料專用介面,我們可以直接拿來用,這個介面中的oid可以理解為每個視頻中的唯一識別符號,它由數字組成,每一個視頻都有唯一的一個oid,那么我們只要找到oid就可以請求相應比賽視頻彈幕的API介面,從而抓取彈幕資料
獲取oid
打開開發者工具,切換到Network選項,然后找到以pagelist為開頭的請求介面

接著找到Request URL這個請求介面,打開新視窗直接用這個API介面請求,如下圖:

當我們直接請求這個API介面時可以看到JSON格式的資料,而在里面的cid就是我們需要的oid,如下所示:
{"code":0,"message":"0","ttl":1,"data":[{"cid":437586584,"page":1,"from":"vupload","part":"第一局 4K","duration":2952,"vid":"","weblink":"","dimension":{"width":1920,"height":1080,"rotate":0}},{"cid":437626309,"page":2,"from":"vupload","part":"第二局 4K","duration":3031,"vid":"","weblink":"","dimension":{"width":1920,"height":1080,"rotate":0}},{"cid":437659159,"page":3,"from":"vupload","part":"第三局 4K","duration":3406,"vid":"","weblink":"","dimension":{"width":1920,"height":1080,"rotate":0}},{"cid":437727348,"page":4,"from":"vupload","part":"第四局 4K","duration":3212,"vid":"","weblink":"","dimension":{"width":1920,"height":1080,"rotate":0}},{"cid":437729555,"page":5,"from":"vupload","part":"第五局 4K","duration":3478,"vid":"","weblink":"","dimension":{"width":1920,"height":1080,"rotate":0}},{"cid":437550300,"page":6,"from":"vupload","part":"開幕式","duration":984,"vid":"","weblink":"","dimension":{"width":1920,"height":1080,"rotate":0}},{"cid":437717574,"page":7,"from":"vupload","part":"奪冠時刻","duration":2017,"vid":"","weblink":"","dimension":{"width":1920,"height":1080,"rotate":0}}]
當然我們也可以點擊**Preview**選項,點擊data,打開資料,而里面的JSON資料是**折疊**的,包括cid在內,如下圖所示:

可以看到,每個cid對應每一個比賽視頻,我們也可以點擊Response選項,里面的資料是真實的資料,意味著資料沒有經過折疊,與直接請求Request URL回傳的JSON資料是一樣的
四、編碼
4.1 爬取資料
定義一個獲取cid的方法
import requests
import json
def get_cid():
url = 'https://api.bilibili.com/x/player/pagelist?bvid=BV1EP4y1j7kV&jsonp=jsonp'
try:
response = requests.get(url,timeout=None)
if response is not None:
return response.text
else:
return Nnone
except Exception as e:
print(e.args)
if __name__ == '__main__':
data = get_cid()
json_data = json.loads(data)
for cid_datas in json_data['data']:
cid = cid_datas.get('cid')
print(cid)
控制臺輸出如下:

拼接URL彈幕資料API介面
if __name__ == '__main__':
data = get_cid()
json_data = json.loads(data)
base_api = 'http://api.bilibili.com/x/v1/dm/list.so?oid='
for cid_datas in json_data['data']:
cid = cid_datas.get('cid')
detail_api = base_api + str(cid)
print(detail_api)
控制臺輸出如下:

一共有7個網址,對應7個EDG比賽視頻的彈幕資料,我們點開第一個網址查看

抓取彈幕資料
從上一張圖可以看到,每一條彈幕資料都在每一個標簽中,面對這種格式我們思考一下用哪種決議工具比較合適?答案當然是正則運算式,接下來我們要獲取7個比賽視頻的22.3萬條資料,代碼如下:
base_api = 'http://api.bilibili.com/x/v1/dm/list.so?oid='
all_api = []
for cid_datas in json_data['data']:
cid = cid_datas.get('cid')
detail_api = base_api + str(cid)
all_api.append(detail_api)
for api in all_api:
edg_datas = get_api_data(detail_api)
edg_datas = re.findall('<d.*?>(.*?)</d>',edg_datas,re.S)
with open('EDG.txt','a',encoding='utf-8') as f:
for edg_data in edg_datas:
print(edg_data)
f.write(edg_data + '\n')
避免亂碼,加上如下代碼:
response.encoding = chardet.detect(response.content)['encoding']
控制臺輸出如下:

由于彈幕資料共有3萬條,這里僅展示EDG.txt部分彈幕資料,如下圖所示:

4.2 資料可視化(詞云圖)
我們已經抓取到彈幕資料,接下來利用EDG背景圖做一個詞云圖

代碼如下:
import jieba
from wordcloud import WordCloud
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
def do_wordcloud():
text = open('EDG.txt','r',encoding='utf-8').read()
text = text.replace('\n','').replace('\u3000','')
text_cut = jieba.lcut(text)
text_cut = ' '.join(text_cut)
#過濾一些沒有關系的詞
stop_words = ['“',',',' ','我','的','是','了',':','?','!','啊','你','嗎',',','我們']
background = Image.open("EDG.jpg")
graph = np.array(background)
word_cloud = WordCloud(font_path='simsun.ttc',
background_color='white',
mask=graph, # 指定詞云的形狀
stopwords=stop_words)
word_cloud.generate(text_cut)
plt.subplots(figsize=(12,8))
plt.imshow(word_cloud)
plt.axis('off')
plt.show()
word_cloud.to_file('edg.png')
控制臺輸出如下:

把迪迦奧特曼背景圖片也制作一波吧,啊哈哈哈!

制作成迪迦奧特曼詞云圖形狀,如下所示:

五、自然語言處理(NLP)
5.1 資料匯入
data = pd.read_csv('EDG.csv')
data = data.head()
print(data)
控制臺輸出如下:

5.2 資料預處理
data = pd.read_csv('EDG.csv')
data = data[['id','content']]
data = data.head(10)
print(data)
控制臺輸出如下:

5.3 情感分析
先安裝一下用于情感分析的Python庫:
pip install snownlp -i https://pypi.doubanio.com/simple
效果如下:

情感分析
由于資料過大,這里僅看部分
from snownlp import SnowNLP
data1['emotion'] = data1['content'].apply(lambda x:SnowNLP(x).sentiments)
data1 = data1.head()
print(data1)
控制臺輸出:

情感資料描述
data1 = data1.describe()
控制臺輸出:

資料說明:emotion的平均值為0.63,中位數為0.67,25%分位數為0.49,可見不到25%的資料造成了整體均值的較大下移,另外上圖的最下面可以看到,情感分析執行時間為48.8s,資料量還是挺大的,
5.4 情感分析直方圖
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
bins = np.arange(0,1.1,0.1) #設定區間
plt.hist(data1['emotion'],bins,color='#4F94CD',alpha=0.9)
plt.xlim(0,1)
plt.xlabel('情感分析')
plt.ylabel('數量')
plt.title('情感分析直方圖')
plt.show()
控制臺輸出:

資料說明:
- 由直方圖可見,彈幕情感呈逐漸上升的趨勢,說明粉絲對EDG奪冠情緒逐漸興奮,很激動;
- 近3萬條彈幕資料中有約4500條彈幕情感分在[0.5,0.6區間內;同時,有約4800條彈幕情感分在[0.8,0.9]區間內,這個區間粉絲的情緒最亢奮,估計是奪冠時刻,哈哈哈!
- 從區間[0.5,0.6]過渡到[0.6,0.7]以及從區間[0.8,0.9]過渡到[0.9,1.0]彈幕情緒出現下降,可能是因為在比賽中出現一些問題或者是比賽落幕了
5.5 關鍵詞提取
from jieba import analyse
key_words = analyse.extract_tags(sentence=text_cut,topK=10,withWeight=True,allowPOS=())
print(key_words)
控制臺輸出:

資料說明:
- 以上關鍵詞顯示,粉絲發的彈幕中“冠軍”是最多的,然后是“翻譯”,”我們”,“臥槽”,“小姐姐”,“EDG”,“淚目“,”圣槍哥“,”賀電“,”edg“,由此看來,EDG真的很受歡迎,翻譯小姐姐也挺受歡迎的,這在上面的詞云圖中也可以看得出來
引數說明:
- sentence是需要提取的字串,必須是str型別,不能是list
- topK表示提取前多少個關鍵字
- withWeight表示是否回傳每個關鍵詞的權重
- allowPOS表示允許提取的詞性,默認提取地名(ns)、名詞(n)、動名詞(vn)、動詞(v)
5.6 積極彈幕與消極彈幕
計算積極彈幕與消極彈幕各自的數目:
pos,neg = 0,0
for i in data1['emotion']:
if i >= 0.5:
pos += 1
else:
neg += 1
print(f'積極彈幕資料為:{pos}' + '\n' + f'消極彈幕資料為:{neg}')
控制臺輸出:

積極彈幕資料為:17941
消極彈幕資料為:6054
5.7 餅圖分析
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
pie_labels = 'positive','negative'
plt.pie([pos,neg],labels=pie_labels,autopct='%1.2f%%',shadow=True)
plt.show()
控制臺輸出:

由上圖可見,由74.77%的彈幕資料是積極的,有25.23%的彈幕資料是消極的,總體來看,積極彈幕還是比較多的
5.8 消極彈幕分析
取出部分消極彈幕資料
data2 = data1[data1['emotion'] < 0.5]
data2 = data2.head()
print(data2)
控制臺輸出:

資料說明:
- 上圖中的“回血”,“求生欲”等消極彈幕有可能是EDG戰隊或者韓國隊比賽不佳造成的
六、總結
PIL庫
jieba庫
numpy庫
pandas庫
requests庫
wordcloud庫
matplotlib庫
json,re,chardet庫
snownlp情感分析庫
七、完整專案下載
本人博客園原文鏈接:閱讀原文
完整專案下載鏈接:下載
本人原創公眾號原文鏈接:閱讀原文
原創不易,如果覺得有趣好玩,希望可以隨手點個贊,拜謝各位老鐵!
最近發現CSDN上好多人抄襲本人博客,還比我熱度高,哎!畢竟是10月份才剛剛開始寫博客,雖然是18年創建的賬號,知名度和粉絲沒有別人高啊!
八、作者Info
作者:小鴻的摸魚日常,Goal:讓編程更有趣!
原創微信公眾號:『小鴻星空科技』,專注于演算法、爬蟲,網站,游戲開發,資料分析、自然語言處理,AI等,期待你的關注,讓我們一起成長、一起Coding!
轉載說明:務必注明來源(注明:來源于公眾號:小鴻星空科技, 作者:小鴻的摸魚日常)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/356888.html
標籤:AI
上一篇:PyTorch學習筆記
下一篇:【機器學習】回歸演算法-精講
