詳解python爬取彈幕與數(shù)據(jù)分析
很不幸的是,由于疫情的關(guān)系,原本線下的AWD改成線上CTF了。這就很難受了,畢竟AWD還是要比CTF難一些的,與人斗現(xiàn)在變成了與主辦方斗。
雖然無奈歸無奈,但是現(xiàn)在還是得打起精神去面對下一場比賽。這個開始也是線下的,決賽地點在南京,后來是由于疫情的關(guān)系也成了線上。
當然,比賽內(nèi)容還是一如既往的得現(xiàn)學,內(nèi)容是關(guān)于大數(shù)據(jù)的。
由于我們學校之前并沒有開設(shè)過相關(guān)培訓,所以也只能自己琢磨了。
好了,廢話先不多說了,正文開始。
一.比賽介紹
大數(shù)據(jù)總體來說分為三個過程。
第一個過程是搭建hadoop環(huán)境。
這個開始我也挺懵的,不過后來看了個教程大概懂了。總的來說,hadoop就是一個集成環(huán)境,這個環(huán)境里面包含了很多軟件。
這些軟件的功能各不相同,比如文件分布式(原諒我也忘了叫啥),大概作用就是假設(shè)你電腦有1個g大小,但是一個文件有10個g,那么你就可以用這個系統(tǒng),將文件割成10份分別儲存。
總的來說,就是為了大數(shù)據(jù)而服務(wù)的一個環(huán)境。
第二個過程就是爬取數(shù)據(jù)。
這個依據(jù)比賽的要求而定,我記得初賽的時候是要求爬取一個開源的電商網(wǎng)站,名字好像是SHOPXO。這個有爬蟲的基礎(chǔ)的同學可以去試下。
決賽還沒比,不過好像是要爬取視頻的彈幕。這個要比單純的爬取視頻麻煩一點,因為每個網(wǎng)站對彈幕的算法不一樣。
一會兒我會寫兩個爬蟲,分別爬取B站和A站的彈幕你們就知道了。
第三個過程就是分析數(shù)據(jù)。
這個說實話我也不太清楚。分析這一步其實python就可以做,但是貌似又得在那個環(huán)境里做。。。挺懵的,所以這里就不詳細寫了。
在寫這篇帖子之前,我還寫過一篇關(guān)于awd比賽的東西。不過由于其中涉及到很多比較特殊的東西,暫時無法外傳,所以我就先設(shè)置成私密的了。
關(guān)于大數(shù)據(jù)其實我和你們一樣是新手,只不過以前因為一些需要剛好學過爬蟲,因此我負責的就是第二塊內(nèi)容。接下來我也會通篇講一些爬蟲和數(shù)據(jù)分析的東西。
二.爬蟲
這個可以說是大數(shù)據(jù)里面很重要的東西了,因為即使你前面分析做的再好,沒有數(shù)據(jù)供你分析又有什么用呢?所以,學好爬蟲。
爬蟲其實是一種代稱,只是功能比較特殊,所以這么叫。在沒學過爬蟲之前,先想想看,我們正常是如何獲取一些信息呢?就比如我們想知道周杰倫的歌單都有什么的時候。
第一步肯定是去百度搜索周杰倫,然后我們就可以在qq音樂之類的音樂網(wǎng)站上看到周杰倫的歌單。爬蟲也得這樣。
它沒有你想象的那么神奇,肯定是要在某些網(wǎng)站上操作才行。
接著,你就可以一點一點的記錄下來周杰倫的信息。我們的爬蟲實現(xiàn)的也是這樣的過程,只不過你一秒鐘只能訪問一個頁面,而爬蟲一秒鐘可以訪問幾萬個頁面。
好了,關(guān)于爬蟲的更詳細的東西就先不說了,我們不是專門講爬蟲的。csdn上面有很多寫爬蟲的教程,都很詳細。
我們主要的目的是進行實戰(zhàn)。
三.爬取網(wǎng)站彈幕
本來是想以網(wǎng)站視頻信息作為題目的,但是那個實在是沒啥難度,正好比賽用得到彈幕,干脆就講講彈幕怎么爬取吧。
1.A站
A站相對于B站要簡單一點。我們先觀察網(wǎng)頁。比如,這個是我隨便打開的一個視頻。
現(xiàn)在網(wǎng)站上的這些數(shù)據(jù)大部分都是動態(tài)的,因此我們不能直接用html解析器來解析網(wǎng)頁,得直接爬取xhr里面的數(shù)據(jù)。
先按F12抓包。然后我們在搜索欄中隨便搜索一條我們的彈幕。
很幸運,只有一個。我們雙擊這個查找的結(jié)果并進行觀察。點到privew,可以發(fā)現(xiàn)這里面包含了我們所有的彈幕。
因此,這種網(wǎng)站直接爬取就行了。點到headers,我們觀察參數(shù)以及請求方式。
ok。這些得到了以后,上腳本。
import requests url="https://www.acfun.cn/rest/pc-direct/new-danmaku/poll" headers={ "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36", "cookie":"" #注意,cookie要填你自己的。A站有些特殊,爬取的時候需要加上cookie。 } data={ "videoId":"15779946", "lastFetchTime":"0", "enableAdvanced":"true" } html=requests.post(url,headers=headers,data=data) html=html.json() html=html["added"] for i in html: print(i["body"])
效果如圖。
數(shù)量我數(shù)了一下,剛好是這個視頻的彈幕數(shù)。你們可以添加自己的東西上去,比如增加寫入文件啥的功能。
2.B站
這個有點特殊了。B站的彈幕是另一種算法。
B站將彈幕單獨剝離出來到了一個網(wǎng)頁上,需要視頻對應(yīng)的cid才可以獲得到彈幕對應(yīng)的碼,然后獲得視頻的彈幕信息。舉個例子:【嗶哩嗶哩2019拜年祭】
首先,我們要獲取到視頻的視頻號以前是av號,現(xiàn)在是bv號。
然后將這個鏈接加上你的bv號。這個是嗶哩嗶哩的一個api,可以獲得cid。
https://api.bilibili.com/x/player/pagelist?bvid=BV17t411y7R1&jsonp=jsonp
將連接中的bvid換成bv號。
如圖,我們發(fā)現(xiàn)了視頻有4個cid。
接著我們使用下一個api,這樣就可以獲得彈幕了。
https://comment.bilibili.com/76457841.xml
將后面的數(shù)字換成剛找到的cid。
結(jié)果如圖:
很好。這就是我們手動獲得彈幕的流程,接下來就是用爬蟲做出來就行了。
第一步,將bv轉(zhuǎn)成av號。其實你可以直接用bv號,但是由于我做這個帖子之前的時候用的是av號找的,所以加了這么一步。
這一步直接去網(wǎng)上找工具就行了,有很多,就不往代碼上面加了。
第二部,用剛才給的第二個api獲得cid。我們使用爬蟲即可,將網(wǎng)址構(gòu)造成規(guī)定的格式。
https://www.bilibili.com/widget/getPageList?aid=?
問號換成aid。
第三步,爬取??梢钥吹轿覀冏罱K返回的是一個xml文件,所以用爬蟲里面的xml解析器解析即可。
別的就不廢話了,直接上代碼。有啥沒看懂的評論區(qū)問。
import requests from bs4 import BeautifulSoup import lxml aid=input("請輸入av號:如果是bv碼請轉(zhuǎn)換為av號\n") file_name=input("請輸入保存文件名:\n") f=open(file_name,"a",encoding='utf-8') headers={ "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36" } get_cid="https://www.bilibili.com/widget/getPageList?aid="+aid cid_list=eval(requests.get(get_cid).text) for cid in cid_list: cid=cid["cid"] xml="https://comment.bilibili.com/"+str(cid)+".xml" html=requests.get(xml,headers=headers) html.encoding=html.apparent_encoding soup=BeautifulSoup(html.text,"xml").find_all("d") for dm in soup: f.write(dm.text+"\n") f.close()
這個是直接將彈幕文件保存到本地了,為了方便后續(xù)的分析。結(jié)果如圖。
一共是九萬多條彈幕。
行了,剩下的就懶得寫了。
四.數(shù)據(jù)分析
要說分析的話其實這個是很廣的,得依據(jù)特定的要求來做。
先說說第一個,高頻詞統(tǒng)計。
代碼是我copy的,簡單但是好用。
(將上一步的文件放到和腳本同一個目錄下)
import jieba.analyse f =open(r'bilibil周年慶.txt',encoding='utf-8')#打開文件 text=f.read() #讀取文件 text_list=jieba.analyse.extract_tags(text,topK=40)#進行jieba分詞,并且取頻率出現(xiàn)最高的40個詞 text_list=",".join(text_list)#用空格將這些字符串連接起來 print(text_list)
如圖,40個出現(xiàn)字數(shù)最多的詞匯就被統(tǒng)計出來了。
由于是機器識別,難免不準,所以不要在意這些莫名其妙出現(xiàn)的次。
在說說第二個,情感分析。這個是我猜測可能會用的到的東西。
我們這個可以直接用baiduAPI來做,要比我們自己的寫的好。這個api會將所有的數(shù)據(jù)進行情感預(yù)測,并且返回積極或者消極的概率。
不過你首先得去申請一個百度api的賬號。這個就不說了,百度有教程。
代碼也是我copy的。首先感謝下原作者,寫的真的很棒。
(原本是要兩個腳本,我改進了一下,寫成了一個腳本。這個腳本僅僅測試了兩個詞,如果想對文件進行分析,稍微改動一下就行了。)
import re import requests import json # 將text按照lenth長度分為不同的幾段 def cut_text(text, lenth): textArr = re.findall('.{' + str(lenth) + '}', text) textArr.append(text[(len(textArr) * lenth):]) return textArr # 返回多段值 def get_emotion(access_token,data): # 情感分析 # 定義百度API情感分析的token值和URL值 token = access_token url = 'https://aip.baidubce.com/rpc/2.0/nlp/v1/sentiment_classify?charset=UTF-8&access_token={}'.format(token) # 百度情感分析API的上限是2048字節(jié),因此判斷文章字節(jié)數(shù)小于2048,則直接調(diào)用 if (len(data.encode()) < 2048): new_each = { 'text': data # 將文本數(shù)據(jù)保存在變量new_each中,data的數(shù)據(jù)類型為string } new_each = json.dumps(new_each) res = requests.post(url, data=new_each) # 利用URL請求百度情感分析API # print("content: ", res.content) res_text = res.text # 保存分析得到的結(jié)果,以string格式保存 result = res_text.find('items') # 查找得到的結(jié)果中是否有items這一項 positive = 1 if (result != -1): # 如果結(jié)果不等于-1,則說明存在items這一項 json_data = json.loads(res.text) negative = (json_data['items'][0]['negative_prob']) # 得到消極指數(shù)值 positive = (json_data['items'][0]['positive_prob']) # 得到積極指數(shù)值 print("positive:",positive) print("negative:",negative) # print(positive) if (positive > negative): # 如果積極大于消極,則返回2 return 2 elif (positive == negative): # 如果消極等于積極,則返回1 return 1 else: return 0 # 否則,返回0 else: return 1 else: data = cut_text(data, 1500) # 如果文章字節(jié)長度大于1500,則切分 # print(data) sum_positive = 0.0 # 定義積極指數(shù)值總合 sum_negative = 0.0 # 定義消極指數(shù)值總和 for each in data: # 遍歷每一段文字 # print(each) new_each = { 'text': each # 將文本數(shù)據(jù)保存在變量new_each中 } new_each = json.dumps(new_each) res = requests.post(url, data=new_each) # 利用URL請求百度情感分析API # print("content: ", res.content) res_text = res.text # 保存分析得到的結(jié)果,以string格式保存 result = res_text.find('items') # 查找得到的結(jié)果中是否有items這一項 if (result != -1): json_data = json.loads(res.text) # 如果結(jié)果不等于-1,則說明存在items這一項 positive = (json_data['items'][0]['positive_prob']) # 得到積極指數(shù)值 negative = (json_data['items'][0]['negative_prob']) # 得到消極指數(shù)值 sum_positive = sum_positive + positive # 積極指數(shù)值加和 sum_negative = sum_negative + negative # 消極指數(shù)值加和 # print(positive) print(sum_positive) print(sum_negative) if (sum_positive > sum_negative): # 如果積極大于消極,則返回2 return 2 elif (sum_positive == sum_negative): # 如果消極等于于積極,則返回1 return 1 else: return 0 # 否則,返回0 def main(): # client_id 為官網(wǎng)獲取的API Key, client_secret 為官網(wǎng)獲取的Secret Key #這兩個我都空出來了,你用你的填上就行了。 client_id="" client_secret="" host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id='+client_id+'&client_secret='+client_secret response = requests.get(host) list_new=eval(response.text) access_token=list_new["access_token"] txt1 = "你好優(yōu)秀" txt2 = "難過!" print("txt1測試結(jié)果:",get_emotion(access_token,txt1)) print("txt2測試結(jié)果:",get_emotion(access_token,txt2)) if __name__ == "__main__": main()
效果如圖。
剩下的比如折線圖什么的就不寫了,百度都有。
到此這篇關(guān)于詳解python爬取彈幕與數(shù)據(jù)分析的文章就介紹到這了,更多相關(guān)pythonpython爬彈幕數(shù)據(jù)分析內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
PyCharm利用pydevd-pycharm實現(xiàn)Python遠程調(diào)試的詳細過程
這篇文章主要介紹了PyCharm利用pydevd-pycharm實現(xiàn)Python遠程調(diào)試,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-09-09基于pytorch的RNN實現(xiàn)字符級姓氏文本分類的示例代碼
當使用基于PyTorch的RNN實現(xiàn)字符級姓氏文本分類時,我們可以使用一個非常簡單的RNN模型來處理輸入的字符序列,并將其應(yīng)用于姓氏分類任務(wù),本文給大家舉了一個基本的示例代碼,需要的朋友可以參考下2023-12-12基于MATLAB和Python實現(xiàn)MFCC特征參數(shù)提取
這篇文章主要介紹了基于MATLAB和Python實現(xiàn)MFCC特征參數(shù)提取,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-08-08淺談Keras中shuffle和validation_split的順序
這篇文章主要介紹了淺談Keras中shuffle和validation_split的順序,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06Python標準庫中內(nèi)置裝飾器@staticmethod和@classmethod
裝飾器是Python中強大而靈活的功能,用于修改或增強函數(shù)或方法的行為,本文就來介紹一下Python標準庫中內(nèi)置裝飾器@staticmethod和@classmethod,感興趣的可以了解一下2023-10-10