日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python爬取B站视频历史弹幕,并去除同标签的重复弹幕,暴力拿下所有弹幕。

發布時間:2023/12/20 python 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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,json

json庫是為了在月份里提取有效日期所使用的,其他的都好理解。

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))


實際上這樣編寫,會出現如上圖所示的情況,我把這樣的后綴加到基出網址上訪問,得到的不是我們需要的內容,我們需要對這樣的進行替換,使它變成有效的后綴。

for s1 in range(len(y_m)):y_m[s1]=re.sub('-010','-10',y_m[s1])y_m[s1]=re.sub('-011','-11',y_m[s1])y_m[s1]=re.sub('-012','-12',y_m[s1])

上面我編寫的代碼,出來的效果是非常成功的。

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個內容進行爬取,都是用的正則,看自己習慣吧,自己喜歡用那個就好。

dm=[]#彈幕主體 sjend=[]#彈幕發布時間 spsjend=[]#彈幕在視頻中出現的位置 for _m_d in Month_day:q=requests.get('https://api.bilibili.com/x/v2/dm/history?type=1&oid='+oid+'&date='+_m_d,headers=h)txt=q.content.decode("utf-8")dm=dm+re.findall('<d p=.*?>(.*?)</d>',txt)sj=re.findall('<d p=".*?,.*?,.*?,.*?,(.*?),.*?">.*?</d>',txt)for zy in sj:zy=time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime(int(zy)))sjend.append(zy)spsj=re.findall('<d p="(.*?),.*?,.*?,.*?,.*?,.*?">.*?</d>',txt)for zy1 in spsj:zy1=time.strftime('%M:%S', time.gmtime(int(re.sub('\.\d+','',zy1))))spsjend.append(zy1)print(oid+'的'+_m_d+"已完成")time.sleep(20)

在中間使用到了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站视频历史弹幕,并去除同标签的重复弹幕,暴力拿下所有弹幕。的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。