用python爬取B站彈幕並製作詞雲
先Po效果圖,這是去年9月某期逗魚時刻的彈幕詞頻分析,就是吾王巨經典的「我給XXX做牛做馬」體剛剛興起的那陣做的詞雲。
這個程序在我去年9月份左右的時候就寫好了,時隔半年威力依舊不減當年,現在回頭看這段代碼已經完全不知所云了,所以想在徹底忘掉之前記錄在萬能的互聯網上。
運行必要庫:urllib.request,re,io,gzip,selenium
必要瀏覽器:火狐(版本不能太新)
主體代碼如下,因為selenium中的page_source參數得到的網頁源碼和urllib.requests有時候不一樣,所以我在這裡都用了。。因此代碼顯得有些冗長,使用gzip的原因是b站頁面貌似是gzip編碼的方式,需要額外進行處理(這部分我也不懂,我google出來的解決方案就是導入gzip包然後這個那個的)。主要思路就是獲取網頁源碼,用正則表達式找到CID號,然後進到對應的存放有所有彈幕的頁面,繼續用正則表達式把時間戳和彈幕內容篩出來,輸入用戶所希望的天數後,再簡單處理一下彈幕內容就可以導出成文件了。經過測試一般視頻可行,番劇彈幕還是不能下載。
用戶需要自行改動的部分包括如下兩個路徑,上面那個系統路徑是用戶希望存放彈幕的位置,下面那個鏈接改成想要抓取的視頻即可。
OK,抓取成功後隨便在網上找個詞雲網站,導入你的文本就可以做出自己想要的模樣了。有其他需求的同學還可以利用結巴分詞來分析詞頻等,做一些圖表之類的來做一些另類的研究什麼的。= =。
#不加encoding的話有可能會報錯 with open(C:/PythonProjects/data/+ str(i) + DayAgoDanmu.txt,w,encoding=utf-8) as NDaysDanmuFile: NDaysDanmuFile.write(RipeDanmu) print(Done!)#要抓取的視頻url = https://www.bilibili.com/video/av22945597-------------------------以下為主代碼------------------------------------------import urllib.request as urimport reimport ioimport gzipfrom selenium import webdriverdef url_open(url): req = ur.Request(url) # 添加一個文件頭,需要先用Request,Request存在的意義是便於在請求的時候傳入一些信息,而urlopen則不能 req.add_header(User-Agent, Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36) response = ur.urlopen(req) if response.info().get(Content-Encoding) == gzip: buf = io.BytesIO(response.read()) gzip_f = gzip.GzipFile(fileobj=buf) html = gzip_f.read() else: html = response.read() return htmldef Get_History_DanMu(days=1): #獲取彈幕時間戳和數量信息 Days_Num = len(TimeAndNumber) while int(days) > Days_Num: print(所輸入時間大於該視頻的年齡) days = input(請重新輸入) else: print(網頁的CID號為 + cidNumber) for i in range(int(days)): if i == 0: print(今天的時間戳為 + TimeAndNumber[Days_Num - 1][0] + | + 今天的彈幕數量為 + TimeAndNumber[Days_Num - 1][1]) else: print(str(i) + 天前的時間戳為 + TimeAndNumber[-1 - i][0] + | + str(i) + 天前的彈幕數量為 + TimeAndNumber[-1 - i][1]) #下載彈幕 # 下載N天前的彈幕並且處理和存放 for i in range(int(days)): if i == 0: print(正在下載今天的彈幕……) else: print(正在下載 + str(i) + 天前的彈幕……) NDays_DanMu_Url = http://comment.bilibili.com/ + dmroll, + TimeAndNumber[-1 - i][0] + , + cidNumber browser = webdriver.Firefox() browser.get(NDays_DanMu_Url) Raw_NDays_Danmu = browser.page_source browser.close() NDaysDanmuPattern = re.compile(<d p=".+?">(.+?)</d>, re.S) RipeDanmu = re.findall(NDaysDanmuPattern, Raw_NDays_Danmu) RipeDanmu =
.join(RipeDanmu) #不加encoding的話有可能會報錯 with open(C:/PythonProjects/data/+ str(i) + DayAgoDanmu.txt,w,encoding=utf-8) as NDaysDanmuFile: NDaysDanmuFile.write(RipeDanmu) print(Done!)#要抓取的視頻url = https://www.bilibili.com/video/av22945597#獲取網頁內容html = url_open(url).decode(utf-8)#尋找當前網頁CID號pattern = re.compile(rcid=(.+?)&aid=.+?&pre_ad)cidNumber1 = re.findall(pattern,html)print(cidNumber1)cidNumber = cidNumber1[0]#找到存放所有彈幕時間戳的網頁AllDanmuUrl = http://comment.bilibili.com/rolldate, + cidNumber#DanMu = url_open(AllDanmuUrl).decode(utf-8),這個方法不行#設置瀏覽器browser = webdriver.Firefox()#讀取上述網頁內容browser.get(AllDanmuUrl)DanMu = browser.page_sourcebrowser.close()print(DanMu)#正則表達式匹配全部時間戳和對應彈幕數量pattern = re.compile(r{"timestamp":"(.+?)","new":"(.+?)"})TimeAndNumber = re.findall(pattern,DanMu)days = input(你希望下載幾天的彈幕?)Get_History_DanMu(int(days))
我自己也很清楚代碼寫的超級亂,因為是新手,初學python之後開腦洞寫的東西,大佬們如果有興趣的話還望指點一下,感謝!
推薦閱讀:
※為什麼做django或者rails開發的都更傾向於用Linux系統?
※[13] Python條件判斷語句(四)
※2018年軟體測試行業預測,手工測試已死?
※黃哥Python 告訴你類到底是一個啥東東。
※Mixin是什麼概念?