python爬取B站视频历史弹幕,并去除同标签的重复弹幕,暴力拿下所有弹幕。
嘻嘻嘻,今天我們來爬小B站的彈幕。
文章目錄
- 前言
- 一、爬取歷史彈幕的思路講解
- 1.如何找到彈幕的爬取位置
- 2.如何找到歷史彈幕的位置
- 二、代碼講解部分
- 1.引入庫
- 2.編寫自己的headers
- 3.編寫視頻的oid與爬取的開始年份與結束年份
- 4.編寫歷史月份的網址后綴
- 5.爬取有效的歷史彈幕網址的日期后綴
- 5.訪問每一個歷史彈幕網址,爬取有效信息
- 6.寫字典,構建數據框
- 6.去重數據
- 總結
- 本次爬取僅作為學習研究使用
前言
在寫這篇博客前,我也在csdn上搜索了關于爬取B站彈幕的內容,怎么說呢,關于歷史彈幕的爬取實際上是少的。
這個也好理解,因為有些B站視頻它從那個發布到爬取的時候彈幕內容都不到3000條(我印象里彈幕列表里面是顯示的最近的3000條),自然也沒有爬取歷史彈幕的必要了,其實實際上是可以得到的,我不僅要得到,也需要得到實際上不重復的,這也算補了csdn這塊爬蟲的空缺。
以下是本篇文章正文內容。
一、爬取歷史彈幕的思路講解
1.如何找到彈幕的爬取位置
這個也是爬取彈幕信息的第一步,我開始覺得是十分簡單,但是實際操作起來還是有難度的。我們用B站視頻尋味順德為例。
進入谷歌開發者工具,點擊Network,展開彈幕列表,多點擊幾次查看歷史歷史彈幕,會出現很多xhr文件來,如果后面內容比較多可以點左上角的禁止符號,面板上的內容就會清理掉。
其實實際上一直點查看歷史彈幕,是無法爬取到歷史彈幕的,或者說連默認的彈幕列表里面的也爬不到,我們需要的是一個開頭是history的文件,該文件的網址后綴是年月日形式的。
找到這個文件只需要先點擊查看歷史彈幕,再在頁面上選擇當日的(這個的是默認的最近多少條也是大部分的博主選擇的爬取網址,這個網址是沒有日期后綴的)或者其他日子的就可以在Network出現相應內容。
進入網址,就會發現這實際上就是一個又一個彈幕,其實到這里如果是爬取默認的彈幕的話,這塊網站的部分就可以結束了,直接復制網址,爬取就歐克,不過歷史彈幕的才是剛剛開始。
2.如何找到歷史彈幕的位置
我們依舊是在查看歷史彈幕這個選項里面下心思,那么網址的后綴是可變的那么直接編寫網址的后綴不就好了,實際是方案是可行的,不過有些繁瑣了。
我在網址分析的時候發現B站會把有新彈幕的日期存在一個xhr文件里面,找到這個文件也很簡單,只需要在查看歷史彈幕那塊進行月份的切換,邊切邊在Network找文件前綴是index,網址的后綴是年月形式的。
訪問的結果是這樣的,其實在這里大致的思路已經出來了,編寫月份的網址,循環遍歷月份的網址,提取出來含有新彈幕的日期,再通過這些日期編寫當天的歷史彈幕的網址,最后循環遍歷將彈幕信息全部爬出來,爬取結束。
二、代碼講解部分
1.引入庫
代碼如下:
import re,requests,time,pandas as pd,jsonjson庫是為了在月份里提取有效日期所使用的,其他的都好理解。
2.編寫自己的headers
參數還是谷歌開發者工具里找就可以找到,字典形式用鍵值對連接起來,這里就不打完整代碼了,大家自己都用自己的就好,我一般用的是cookie和user-agent這兩個參數,當然爬B站彈幕這兩個也是必備的。
h={'cookie':'自己的cookie','user-agent':'自己的user-agent'}3.編寫視頻的oid與爬取的開始年份與結束年份
這個oid實際上在歷史月份與歷史日期的網址都是有的,如果僅僅是爬一次的話,那略過這里也是可以的,后期把循環編寫的部分改掉就好,年份那塊也是一樣,這只是筆者的習慣罷了。
oid='7582034' begin=2019###在這里輸入你需要爬取的最初年份 end=2020###這里是結束年份4.編寫歷史月份的網址后綴
y_m=[]###這個用來存年月份數據 for sz1 in range(begin,end+1):for sz2 in range(1,13):y_m.append(str(sz1)+'-0'+str(sz2))
實際上這樣編寫,會出現如上圖所示的情況,我把這樣的后綴加到基出網址上訪問,得到的不是我們需要的內容,我們需要對這樣的進行替換,使它變成有效的后綴。
上面我編寫的代碼,出來的效果是非常成功的。
5.爬取有效的歷史彈幕網址的日期后綴
前面的月份的后綴在這里也就用到了https://api.bilibili.com/x/v2/dm/history/index?type=1&oid='+oid+'&month='+月份后綴
這里需要看一下月份的網址,我在這截了一段。
{“code”:0,“message”:“0”,“ttl”:1,“data”:[“2020-08-01”,“2020-08-02”,“2020-08-03”,“2020-08-04”,“2020-08-05”,“2020-08-06”,“2020-08-07”,“2020-08-08”,“2020-08-09”,“2020-08-10”,“2020-08-11”,“2020-08-12”,“2020-08-13”,“2020-08-14”,“2020-08-15”,“2020-08-16”,“2020-08-17”,“2020-08-18”,“2020-08-19”,“2020-08-20”,“2020-08-21”,“2020-08-22”,“2020-08-23”,“2020-08-24”,“2020-08-25”,“2020-08-26”,“2020-08-27”,“2020-08-28”,“2020-08-29”,“2020-08-30”,“2020-08-31”]}
很明顯的用json就一部到位json.loads(''.join(文本))['data'],那么這里的代碼也迎刃而解了。
Month_day=[]#這里用來存有效的日期 for _y_m in y_m:Q=requests.get('https://api.bilibili.com/x/v2/dm/history/index?type=1&oid='+oid+'&month='+_y_m,headers=h)if re.findall('("data":null)',Q.text)==['"data":null']:print(oid+'的'+_y_m+'無效')else:Month_day=Month_day+json.loads(''.join(Q.text))['data']print(oid+'的'+_y_m+'已到位')time.sleep(20)這里的時間休眠設了20秒,實際上不需要那么長,大概來個5秒就好,我設置的長是因為我都是晚上爬,時間多(實際是害怕被B站關小黑屋)。
這里也做了一個判斷,是因為前面編寫月份后綴的時候,沒有辦法排錯的,在這里進行了排錯,下面的是未存在的月份的頁面反饋。
這里也是直接用正則做的判斷,看看運行中打印的效果,還是蠻不錯的。
5.訪問每一個歷史彈幕網址,爬取有效信息
這塊就進行到爬取歷史彈幕的網址了,看看網站吧。
有彈幕的部分,這個好理解,可是前面的數字都代表什么呢,這些要去問問度娘。
那自己需要什么呢,自己自行判斷,博主這里選擇了3個內容進行爬取,都是用的正則,看自己習慣吧,自己喜歡用那個就好。
在中間使用到了time.strftime()這個方法,用來做時間的轉換,要求都是int格式的,所以做了一些操作。
6.寫字典,構建數據框
zd={'彈幕發布日期':sjend,'彈幕內容':dm,'視頻中彈幕的何時發布':spsjend} bg=pd.DataFrame(zd)第五步運行完,爬取的內容就算結束了,這里是運行了10來頁爬到的內容,是十分不錯的,下面就是要做是處理掉三項都重復的數據。
6.去重數據
bgz=bg.drop_duplicates(subset=['彈幕發布日期','彈幕內容','視頻中彈幕的何時發布'])這里采取的是按照多列去重,看看去重完的數據。
25w去重變6000多,但的的確確是這樣的,不過這只是一個來月的數據,并且不是熱播時期,這樣的結果已經很滿意了。
用excel去重的效果也是一樣,證明代碼可行,彈幕積少成多嘛。
總結
這種對歷史彈幕的爬取還是十分容易理解的,不過最后的篩選我考慮的還是少了一些,會不會出現這種情況,在同一秒里同一時刻不同的人發布了相同的彈幕內容。
實際上,這樣的情況我在寫的時候是沒有考慮到的,解決這種的方法還是有的,就是把去重時所考慮的參數增多(增加其他參數),或者再爬取時不用改為標準時間格式,去重后改為標準時間。這樣也可以更加精準一點。
因為B站歷史彈幕的特殊變換,爬取是十分暴力的,不過也得到了可觀的效果,思路比較直接。
第一次編輯時間:2020/09/09
本次爬取僅作為學習研究使用
總結
以上是生活随笔為你收集整理的python爬取B站视频历史弹幕,并去除同标签的重复弹幕,暴力拿下所有弹幕。的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Tomcat概述
- 下一篇: websocket python爬虫_p