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