1.源數據獲取 #
數據源為 B 站視頻評論
在加載新的一頁評論時觀察到訪問的 url
https://api.bilibili.com/x/v2/reply/main?callback=jQuery172020167562580015508_1653393655707&jsonp=jsonp&next=4&type=1&oid=768584323&mode=3&plat=1&_=1653396013955
其中
next: 頁數
oid: 視頻 av 號
訪問時帶上 head
例如{user-agent,"referer":"https://www.bilibili.com"}
可以獲得評論的 json 文件
- 數據預處理;
以 av=13662970"你的名字" 為例
url
=https://api.bilibili.com/x/v2/reply/main?jsonp=jsonp&next=%25d&type=1&oid=13662970
-
修改 page 值爬取 10 頁 json(最後修改獲取 100 頁 100 個 json)
-
讀取 10 個 json 文件獲取評論
data["data"]["replies"][i=0-19]["content"]["message"]
- 每個 json 文件含有 20 個評論修改 i=0 到 19,循環獲得 20 個評論
- 輸出所有評論
3. 數據存儲與管理;#
- 獲取 100 頁 2000 個評論寫入到 comment.txt 文件
4. 模型的選取;#
- 使用 jieba 進行詞頻分析
-
存在很多無意義詞
-
創建 ignore_dict.txt,根據結果排除詞
- 去除後:
詞雲,排除詞
5. 可視化分析。#
file_path="res.csv"
df=pd.read_csv(file_path,encoding="gbk")
df.columns = ["word","frequency"]
print(df.head())
plt.bar(df["word"],df["frequency"])
plt.xlabel('詞')
plt.ylabel('出現次數')
plt.show()
- 讀取 csv 繪圖
用戶等級與點讚量的關係#
like 列表與用戶等級列表
like.append(data["data"]["replies"][i]["like"])
level.append(data["data"]["replies"][i]["member"]["level_info"]["current_level"])
繪圖
plt.bar(level,like)
plt.xlabel('用戶等級')
plt.ylabel('點讚總數')
- 核心代碼以及工具清單
使用的庫:requests
,jieba
,re
,pandas
,matplotlib
,json
,csv
過程
-
from_bilibili_get_json.py--- 獲取評論 json
-
like_level.py--- 根據 json 得到不同等級用戶的被點讚量並繪製柱狀圖
-
dejson.py--- 收集所有評論到 comment.txt
-
詞頻.py - 詞頻分析
-
keshijua.py--- 可視化
from_bilibili_get_json.py
import requests,json
headerbili={
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36
(KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36
Edg/100.0.1185.50",
"referer":"https://www.bilibili.com"
}
'''
next:頁數
oid:視頻av號
'''python
def get_json(page):
url="https://api.bilibili.com/x/v2/reply/main?jsonp=jsonp&next=%d&type=1&oid=13662970"
data = requests.get(url % page,
headers=headerbili).text.encode("utf8")
comm=json.loads(data)
print(comm)
'''
其中ensure_ascii用來規定返回值是否可以包含非ASCII碼。
中文超過ASCII碼範圍,修改ensure_ascii參數值
'''
with open("./json/{}.json".format(page),"w" ,encoding='utf-8') as
f:
f.write(json.dumps(comm, ensure_ascii=False))
for i in range(100):#100頁
get_json(i)
print(i,'n')
# vedioreg = 'class="tap-router">(.*?)</a>'
# aurllist = re.findall(vedioreg, rank, re.S | re.M)
# print(aurllist)
like_level.py
import json
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
*#用來正常顯示中文標籤
*plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號
#有中文出現的情況,需要u'內容'
like= []
level=[]
for e in range(100):
with open("./json/{}.json".format(e),"r",encoding="utf8") as f:
data=json.load(f)
for i in range(20):
like.append(data["data"]["replies"][i]["like"])
level.append(data["data"]["replies"][i]["member"]["level_info"]["current_level"])
print(like,level)
plt.bar(level,like)
plt.xlabel('用戶等級')
plt.ylabel('點讚總數')
plt.show()
dejson.py
import json,csv
comment=[]*#評論列表
for e in range(100):
with open("./json/{}.json".format(e),"r",encoding="utf8") as f:
data=json.load(f)
for i in range(20):
comment.append(data["data"]["replies"][i]["content"]["message"])
with open("comment.txt","w",encoding="utf8") as fp:
writer = csv.writer(fp)
writer.writerow(comment)
print("寫入", comment)#評論的txt文件
詞頻.py
import jieba,re
*#去除標點
*def get_text(file_name):
with open(file_name, 'r', encoding='utf-8') as fr:
text = fr.read()
#刪除的標點
del_ch = ['《',',','》','n','。','、',';','"',
':',',','!','?',' ']
for ch in del_ch:
text = text.replace(ch,'')
return text
file_name = 'comment.txt'
text = get_text(file_name)
vlist = jieba.lcut(text)#調用jieba實現分詞,返回列表
res_dict = {}
#進行詞頻統計
for i in vlist:
res_dict[i] = res_dict.get(i,0) + 1
res_list = list(res_dict.items())
#print(res_list)
#降序排序
res_list.sort(key = lambda x:x[1], reverse = True)
fin_res_list = []
#去除單個字的詞
for item in res_list:
if(len(item[0])>=2):
fin_res_list.append(item)
word_list=[]
words=[]
for i in range(1000):
word,count = fin_res_list[i]
pstr = str(i+1) + ':'
word_list.append(word)
with open('ignore_dict.txt', 'r', encoding='utf-8') as f:
ignore_words = f.read().splitlines()
# 遍歷分詞
for word in word_list:
if word not in ignore_words:#排除詞
word = re.sub(r'[n ]', '', word)
if len(word) < 1:
continue
words.append(word)
# print(pstr, end=' ')
# print(words[i], count)
with open("res.csv","a+")as fa:
fa.write(str(words[i])+","+str(count)+"n")
keshijua.py
import pandas as pd
import matplotlib.pyplot as plt
import wordcloud,jieba
plt.rcParams['font.sans-serif']=['SimHei']
#用來正常顯示中文標籤
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號
#有中文出現的情況,需要u'內容'
#文件目錄
file_path="res.csv"
df=pd.read_csv(file_path,encoding="gbk")
#柱狀圖
def _bar():
df.columns = ["word","frequency"]
print(df.head())
plt.bar(df["word"],df["frequency"])
plt.xlabel('詞')
plt.ylabel('出現次數')
plt.show()
_bar()
#詞雲
with open("comment.txt","r",encoding="utf8")as f:
txt=f.read()
stopwords =
["的","了","我","時","在","你","看","到","沒","不","就","是","人","也","有","和","會",
"一個","沒有","時候","彈幕","自己","什麼","時間","知道","就是","現在","真的","已經","還是","這個","看到","可以","因為"
,"你們","才能","不是","但是","那個","最後","每秒","所以","他們","覺得","怎麼樣","一樣","舉報","這部","大家","不能","當時"
,"一直","一次","然後","還有","這樣","評論","如果","那麼","為什麼","第一次","感謝","只是","這些","之後","忘記","一下","雖然","為了"
,"一定","今天","這麼","不會","這裡","去年","兩個","以後","地方","那些","這種","怎麼","其實","起來","應該","---","發生","只有","天氣"
,"今年","很多","好像","所有","一部","出來","找到","之子","一遍","謝謝","告訴","東西","永遠","的話","五塊","一句","之前","過去","一年"
,"一天","終於","選擇","對於","非常","突然"
]
w=wordcloud.WordCloud(background_color="white",font_path="msyh.ttc",height=600,width=800,stopwords=stopwords)
w.generate(" ".join(jieba.lcut(txt)))
w.to_file("詞雲.png")
忽略詞
根據結果自己寫
一個 沒有 沒有 時候 彈幕 自己 什麼 時間 知道 就是 現在 真的 已經 還是 看到 可以 因為 你們 才能 不是 但是 每秒 所以 他們 覺得 怎麼樣 一樣 舉報 這部 大家 不能 當時 一直 一次 然後 還有 這樣 評論 如果 那麼 為什麼 第一次 感謝 只是 這些 之後 忘記 一下 雖然 為了 一定 今天 這麼 不會 這裡 去年 兩個 以後 地方 那些 這種 怎麼 其實 起來 應該 --- 發生 只有 天氣 今年 很多 好像 所有 一部 出來 找到 之子 一遍 謝謝 告訴 東西 永遠 的話 五塊 一句 之前 過去 一年 一天 終於 選擇 對於 非常 突然
五、結論與心得
開始準備爬取 taptap 評論數據,根據下面博客分析
【Python】爬取 TapTap 原神評論並生成詞雲分析_includei 的博客 - CSDN 博客_爬取 taptap 評論
最後發現評論數據地址需要滑動驗證
但哔哩哔哩評論數據訪問時不需要驗證
六、參考文獻
【Python】爬取 TapTap 原神評論並生成詞雲分析_includei 的博客 - CSDN 博客_爬取 taptap 評論
WordCloud 詞雲圖去除停用詞的正確方法_羅羅攀的博客 - CSDN 博客