溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python怎么爬取B站視頻彈幕

發布時間:2021-11-23 11:28:11 來源:億速云 閱讀:530 作者:iii 欄目:大數據
# Python怎么爬取B站視頻彈幕

## 前言

在B站(嗶哩嗶哩)觀看視頻時,彈幕是其最具特色的功能之一。這些實時飄過的評論不僅增加了視頻的互動性,也蘊含了大量用戶反饋數據。對于數據分析師、內容創作者或愛好者來說,爬取這些彈幕數據可以幫助分析觀眾情緒、熱門話題等。本文將詳細介紹如何使用Python爬取B站視頻彈幕。

---

## 一、準備工作

### 1.1 理解B站彈幕機制
B站的彈幕數據通常存儲在XML或JSON格式的文件中,每個視頻都有對應的彈幕文件(`cid`標識)。需要通過視頻的`bvid`或`aid`先獲取到`cid`,再通過`cid`獲取彈幕。

### 1.2 安裝必要的Python庫
```bash
pip install requests beautifulsoup4 lxml

1.3 目標分析

以B站視頻 BV1GJ411x7h7 為例: 1. 獲取視頻的cid 2. 通過cid請求彈幕接口 3. 解析并存儲彈幕數據


二、獲取視頻CID

2.1 通過API獲取CID

B站提供了公開API來獲取視頻信息,其中包含cid。構造請求URL如下:

import requests

def get_cid(bvid):
    url = f"https://api.bilibili.com/x/player/pagelist?bvid={bvid}&jsonp=jsonp"
    response = requests.get(url)
    if response.status_code == 200:
        data = response.json()
        return data['data'][0]['cid']
    else:
        raise Exception("Failed to get CID")

bvid = "BV1GJ411x7h7"
cid = get_cid(bvid)
print(f"CID: {cid}")

2.2 備用方案:從網頁源碼提取

如果API不可用,可以通過解析視頻頁面獲?。?/p>

from bs4 import BeautifulSoup

def get_cid_from_html(bvid):
    url = f"https://www.bilibili.com/video/{bvid}"
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'lxml')
    script = soup.find("script", text=lambda t: "window.__playinfo__" in str(t))
    # 通過正則提取cid
    import re
    cid = re.search(r'"cid":(\d+)', script.string).group(1)
    return int(cid)

三、獲取彈幕數據

3.1 B站彈幕接口

B站的彈幕接口為:

https://api.bilibili.com/x/v1/dm/list.so?oid={cid}

3.2 請求并解析XML

def get_danmaku(cid):
    url = f"https://api.bilibili.com/x/v1/dm/list.so?oid={cid}"
    response = requests.get(url)
    response.encoding = 'utf-8'
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(response.text, 'lxml')
    danmus = soup.find_all('d')
    return [danmu.text for danmu in danmus]

danmaku_list = get_danmaku(cid)
print(f"獲取到{len(danmaku_list)}條彈幕")

3.3 彈幕數據解析

每條彈幕XML格式如下:

<d p="時間戳,彈幕類型,字體大小,顏色,發送時間,彈幕池,用戶Hash,數據庫ID">彈幕內容</d>

可以進一步解析這些屬性:

import re

def parse_danmaku(danmu):
    pattern = r'<d p="(.*?)">(.*?)</d>'
    matches = re.findall(pattern, str(danmu))
    result = []
    for m in matches:
        attrs = m[0].split(',')
        item = {
            'time': float(attrs[0]),
            'type': int(attrs[1]),
            'size': int(attrs[2]),
            'color': int(attrs[3]),
            'timestamp': int(attrs[4]),
            'content': m[1]
        }
        result.append(item)
    return result

四、數據存儲

4.1 存儲為TXT文件

def save_as_txt(danmaku_list, filename):
    with open(filename, 'w', encoding='utf-8') as f:
        for danmu in danmaku_list:
            f.write(danmu + '\n')

save_as_txt(danmaku_list, 'danmaku.txt')

4.2 存儲為CSV

import pandas as pd

def save_as_csv(parsed_danmaku, filename):
    df = pd.DataFrame(parsed_danmaku)
    df.to_csv(filename, index=False)

save_as_csv(parse_danmaku(danmaku_list), 'danmaku.csv')

4.3 存儲到數據庫(MySQL示例)

import pymysql

def save_to_mysql(parsed_danmaku):
    conn = pymysql.connect(host='localhost',
                         user='root',
                         password='password',
                         database='bilibili')
    cursor = conn.cursor()
    sql = """INSERT INTO danmaku 
             (time, type, size, color, timestamp, content) 
             VALUES (%s, %s, %s, %s, %s, %s)"""
    for item in parsed_danmaku:
        cursor.execute(sql, (item['time'], item['type'], 
                           item['size'], item['color'],
                           item['timestamp'], item['content']))
    conn.commit()
    conn.close()

五、高級技巧

5.1 處理分P視頻

對于多P視頻,需要遍歷所有分P的CID:

def get_all_cids(bvid):
    url = f"https://api.bilibili.com/x/player/pagelist?bvid={bvid}"
    response = requests.get(url)
    return [item['cid'] for item in response.json()['data']]

5.2 異步爬取提升效率

使用aiohttp加速請求:

import aiohttp
import asyncio

async def async_get_danmaku(cid):
    async with aiohttp.ClientSession() as session:
        url = f"https://api.bilibili.com/x/v1/dm/list.so?oid={cid}"
        async with session.get(url) as response:
            text = await response.text()
            soup = BeautifulSoup(text, 'lxml')
            return [d.text for d in soup.find_all('d')]

5.3 繞過反爬機制

  • 添加Headers模擬瀏覽器
  • 使用代理IP
  • 設置請求間隔
headers = {
    'User-Agent': 'Mozilla/5.0',
    'Referer': 'https://www.bilibili.com/'
}
proxies = {'http': 'http://127.0.0.1:1080'}

六、數據分析示例

6.1 彈幕詞云生成

from wordcloud import WordCloud
import jieba

text = ' '.join(danmaku_list)
wordlist = ' '.join(jieba.cut(text))
wc = WordCloud(font_path='simhei.ttf').generate(wordlist)
wc.to_file('danmaku_cloud.png')

6.2 彈幕時間分布分析

import matplotlib.pyplot as plt

times = [d['time'] for d in parsed_danmaku]
plt.hist(times, bins=50)
plt.xlabel('Video Time (s)')
plt.ylabel('Danmaku Count')
plt.show()

七、注意事項

  1. 遵守Robots協議:B站robots.txt對部分路徑有限制
  2. 控制請求頻率:避免高頻請求導致IP被封
  3. 數據用途:僅限個人學習使用,不得用于商業用途
  4. 版權聲明:彈幕數據屬于用戶生成內容,需注意隱私問題

結語

本文詳細介紹了從B站視頻爬取彈幕的完整流程,包括: - 獲取視頻CID的兩種方法 - 請求和解析彈幕XML數據 - 多種存儲方式 - 高級技巧和數據分析示例

通過Python爬取B站彈幕不僅可以幫助我們理解B站的API結構,也為后續的數據分析工作奠定了基礎。希望這篇教程對你有所幫助!

注意:本文所有代碼示例僅供學習參考,實際使用時請遵守B站的相關規定。 “`

(全文約3100字)

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女