手把手教你爬取B站彈幕!


效果

輸入要爬取的視頻的BV號即可爬取該視頻的彈幕。

過程

基本思路

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

1、構造爬取的url

2、解析返回的數據

3、使用json或Xpath或正則表達式提取數據

4、保存數據

尋找url地址

第一步

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

第二步

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

此時請求就變得少了很多,但是依然沒有找到我們需要的彈幕數據,此時才發現我們並沒有點擊播放視頻。

第三步

彈幕是在視頻播放的過程中播放的,理所當然只有當我們播放視頻並且打開彈幕后才會請求彈幕的數據,我們點擊播放。

點擊播放后我們可以發現請求變多了,再次尋找我們發現 168881748.xml 請求的地址便是彈幕數據了。

第四步

到這里我們就想到了,這種地址是怎么請求的呢?不同的視頻請求的地址肯定是不一樣的,應該是js生成的吧!現在我們來搜索一下該文件名``168881748`

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

不出所料是js構成的請求地址,我們可以發現這便是頁面的數據,我們進一步去驗證一下,刷新頁面,查看一下網頁的數據。

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

現在的思路

現在思路就很清晰了

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中的<d></d>中,取出即可
    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()

這里只打印了彈幕,並沒有保存,可以根據自己的需求進行更改!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM