天天看點

java彈幕爬取,手把手教你爬取B站彈幕(超詳細)!

效果

輸入要爬取的視訊的BV号即可爬取該視訊的彈幕。

java彈幕爬取,手把手教你爬取B站彈幕(超詳細)!

過程

基本思路

基本的思路很簡單,還是老步驟:

1、構造爬取的url

2、解析傳回的資料

3、使用json或Xpath或正規表達式提取資料

4、儲存資料

尋找url位址

第一步

剛開始還是從網頁版中尋找url位址,結果請求很多,找了半天也沒有找到

java彈幕爬取,手把手教你爬取B站彈幕(超詳細)!

第二步

于是我們可以通路一下手機版的頁面,而根據常識,彈幕這種東西一般是通過ajax來請求的,是以我們過濾一下,隻看異步請求。

java彈幕爬取,手把手教你爬取B站彈幕(超詳細)!

此時請求就變得少了很多,但是依然沒有找到我們需要的彈幕資料,此時才發現我們并沒有點選播放視訊。

第三步

彈幕是在視訊播放的過程中播放的,理所當然隻有當我們播放視訊并且打開彈幕後才會請求彈幕的資料,我們點選播放。

java彈幕爬取,手把手教你爬取B站彈幕(超詳細)!

點選播放後我們可以發現請求變多了,再次尋找我們發現 168881748.xml 請求的位址便是彈幕資料了。

java彈幕爬取,手把手教你爬取B站彈幕(超詳細)!

第四步

到這裡我們就想到了,這種位址是怎麼請求的呢?不同的視訊請求的位址肯定是不一樣的,應該是js生成的吧!現在我們來搜尋一下該檔案名``168881748`

java彈幕爬取,手把手教你爬取B站彈幕(超詳細)!

很顯然這是構造出來的位址,我們點進去看一下

java彈幕爬取,手把手教你爬取B站彈幕(超詳細)!

不出所料是js構成的請求位址,我們可以發現這便是頁面的資料,我們進一步去驗證一下,重新整理頁面,檢視一下網頁的資料。

java彈幕爬取,手把手教你爬取B站彈幕(超詳細)!

果然在該頁面的文檔中我們找到了

java彈幕爬取,手把手教你爬取B站彈幕(超詳細)!

現在的思路

現在思路就很清晰了

1、通過視訊url擷取彈幕檔案url

2、爬取彈幕檔案url

3、提取資料

代碼實作

# coding=utf-8

import requests

from lxml import etree

import re

class BiliSpider:

def __init__(self,BV):

# 構造要爬取的視訊url位址

self.BVurl = "https://m.bilibili.com/video/"+BV

self.headers = {"User-Agent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Mobile Safari/537.36"}

# 彈幕都是在一個url請求中,該url請求在視訊url的js腳本中構造

def getXml_url(self):

# 擷取該視訊網頁的内容

response = requests.get(self.BVurl, headers = self.headers)

html_str = response.content.decode()

# 使用正則找出該彈幕位址

# 格式為:https://comment.bilibili.com/168087953.xml

# 我們分隔出的是位址中的彈幕檔案名,即 168087953

getWord_url = re.findall(" ‘//comment.bilibili.com/‘+ (.*) +‘.xml‘,", html_str)

getWord_url = getWord_url[0].replace("+","").replace(" ","")

# 組裝成要請求的xml位址

xml_url = "https://comment.bilibili.com/{}.xml".format(getWord_url)

return xml_url

# Xpath不能解析指明編碼格式的字元串,是以此處我們不解碼,還是二進制文本

def parse_url(self,url):

response = requests.get(url,headers = self.headers)

return response.content

# 彈幕包含在xml中的中,取出即可

def get_word_list(self,str):

html = etree.HTML(str)

word_list = html.xpath("//d/text()")

return word_list

def run(self):

# 1.根據BV号擷取彈幕的位址

start_url = self.getXml_url()

# 2.請求并解析資料

xml_str = self.parse_url(start_url)

word_list = self.get_word_list(xml_str)

# 3.列印

for word in word_list:

print(word)

if __name__ == ‘__main__‘:

BVName = input("請輸入要爬取的視訊的BV号:")

spider = BiliSpider(BVName)

spider.run()

這裡隻列印了彈幕,并沒有儲存,可以根據自己的需求進行更改!

原文:https://www.cnblogs.com/wuren-best/p/12566297.html