大会官网https://ais.cn/u/EVz2Y3

大会时间:2026年01月30日-2月1日

国内大会地点:中国-三亚

海外大会地点:美国-芝加哥

前言

随着互联网内容生态的蓬勃发展,B 站作为国内领先的视频内容平台,其热门视频数据蕴含着丰富的用户行为和内容趋势信息。掌握 B 站热门视频数据的爬取方法,不仅能帮助数据分析爱好者挖掘内容价值,也能为内容创作者提供数据参考。本文将从零开始,详细讲解如何使用 Python 实现 B 站热门视频数据的爬取,涵盖请求构造、数据解析、数据存储等核心环节,所有代码均可直接运行,适合 Python 爬虫初学者学习和实践。

摘要

本文以 B 站热门视频页面(https://www.bilibili.com/v/popular/all/)为爬取目标,使用requests库发送 HTTP 请求获取页面数据,通过BeautifulSoup解析 HTML 结构提取核心信息,最终将爬取的视频标题、UP 主、播放量、点赞数等数据存储为 CSV 文件。文中包含完整可运行的代码、详细的代码解析、数据输出结果及核心原理说明,帮助读者深入理解爬虫开发的全流程。

一、环境准备

1.1 所需 Python 库

爬取 B 站热门视频数据需要用到以下核心库,各库的作用如下表所示:

库名称 版本建议 核心作用
requests 2.31.0+ 发送 HTTP 请求,获取网页响应数据
beautifulsoup4 4.12.0+ 解析 HTML/XML 文档,提取目标数据
csv 内置库 将爬取的数据写入 CSV 文件,便于后续分析
time 内置库 设置请求间隔,避免高频请求被封禁
fake-useragent 1.4.0+ 生成随机 User-Agent,模拟浏览器请求

1.2 库的安装

打开终端 / 命令提示符,执行以下命令安装所需库:

bash

运行

pip install requests beautifulsoup4 fake-useragent

二、爬虫核心原理

2.1 HTTP 请求原理

爬虫本质是模拟浏览器向目标网站服务器发送 HTTP 请求,服务器接收到合法请求后返回对应的页面数据(HTML/JSON 等),爬虫再对返回数据进行解析,提取所需信息。

2.2 B 站热门页面数据结构分析

B 站热门视频页面为服务端渲染的 HTML 页面,核心视频数据包含在<li class="video-item matrix">标签内,每个标签对应一个热门视频,包含标题、UP 主、播放量、点赞数、链接等信息,可通过 BeautifulSoup 定位标签并提取数据。

2.3 反爬策略规避

  • 设置随机 User-Agent,模拟不同浏览器请求;
  • 添加请求间隔,避免短时间内大量请求;
  • 遵守 robots 协议,仅爬取公开的非敏感数据。

三、完整代码实现

python

运行

import requests
import csv
import time
from fake_useragent import UserAgent
from bs4 import BeautifulSoup
from requests.exceptions import RequestException

class BilibiliHotCrawler:
    def __init__(self):
        # 初始化请求头,使用随机User-Agent
        self.ua = UserAgent()
        self.headers = {
            'User-Agent': self.ua.random,
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
            'Referer': 'https://www.bilibili.com/',
            'Connection': 'keep-alive'
        }
        # B站热门视频页面URL
        self.url = 'https://www.bilibili.com/v/popular/all/'
        # 存储爬取的数据
        self.video_data = []

    def get_page(self):
        """发送请求,获取页面HTML数据"""
        try:
            # 设置随机请求间隔,避免高频请求
            time.sleep(1 + float(time.time() % 1))
            response = requests.get(
                url=self.url,
                headers=self.headers,
                timeout=10
            )
            # 验证响应状态码
            response.raise_for_status()
            # 设置正确的编码格式
            response.encoding = 'utf-8'
            return response.text
        except RequestException as e:
            print(f"请求失败:{e}")
            return None

    def parse_page(self, html):
        """解析HTML页面,提取视频数据"""
        soup = BeautifulSoup(html, 'html.parser')
        # 定位所有视频项标签
        video_items = soup.find_all('li', class_='video-item matrix')
        
        for item in video_items:
            try:
                # 提取视频标题
                title_tag = item.find('a', class_='title')
                title = title_tag.get_text(strip=True) if title_tag else '无标题'
                
                # 提取视频链接
                video_link = 'https://www.bilibili.com' + title_tag['href'] if title_tag else '无链接'
                
                # 提取UP主名称
                up_tag = item.find('a', class_='up-name')
                up_name = up_tag.get_text(strip=True) if up_tag else '未知UP主'
                
                # 提取播放量
                play_tag = item.find('span', class_='play')
                play_count = play_tag.get_text(strip=True) if play_tag else '0'
                
                # 提取弹幕数
                danmaku_tag = item.find('span', class_='danmaku')
                danmaku_count = danmaku_tag.get_text(strip=True) if danmaku_tag else '0'
                
                # 提取点赞数(需从属性中获取)
                like_tag = item.find('i', class_='icon-like')
                like_count = like_tag.parent.get('title', '0').replace('点赞数 ', '') if like_tag else '0'
                
                # 提取视频时长
                duration_tag = item.find('span', class_='duration')
                duration = duration_tag.get_text(strip=True) if duration_tag else '00:00'
                
                # 组装数据
                video_info = {
                    '标题': title,
                    'UP主': up_name,
                    '播放量': play_count,
                    '弹幕数': danmaku_count,
                    '点赞数': like_count,
                    '时长': duration,
                    '视频链接': video_link
                }
                self.video_data.append(video_info)
                print(f"已爬取:{title} - {up_name}")
                
            except Exception as e:
                print(f"解析单条视频数据失败:{e}")
                continue

    def save_to_csv(self):
        """将爬取的数据保存为CSV文件"""
        if not self.video_data:
            print("无数据可保存")
            return
        
        # 定义CSV表头
        headers = ['标题', 'UP主', '播放量', '弹幕数', '点赞数', '时长', '视频链接']
        # 保存为UTF-8编码的CSV文件(兼容Excel)
        with open('bilibili_hot_videos.csv', 'w', newline='', encoding='utf-8-sig') as f:
            writer = csv.DictWriter(f, fieldnames=headers)
            writer.writeheader()
            writer.writerows(self.video_data)
        
        print(f"数据保存完成!共爬取{len(self.video_data)}条热门视频数据,文件名为:bilibili_hot_videos.csv")

    def run(self):
        """执行爬虫主流程"""
        print("开始爬取B站热门视频数据...")
        # 1. 获取页面数据
        html = self.get_page()
        if not html:
            print("页面获取失败,爬虫终止")
            return
        
        # 2. 解析页面数据
        self.parse_page(html)
        
        # 3. 保存数据
        self.save_to_csv()
        print("爬虫执行完毕!")

if __name__ == '__main__':
    # 实例化并运行爬虫
    crawler = BilibiliHotCrawler()
    crawler.run()

四、代码解析

4.1 类结构设计

BilibiliHotCrawler类封装了爬虫的所有功能,主要包含以下核心方法:

  • __init__:初始化请求头、目标 URL、数据存储列表等;
  • get_page:发送 HTTP 请求,获取页面 HTML,包含异常处理和请求间隔设置;
  • parse_page:使用 BeautifulSoup 解析 HTML,提取视频核心信息;
  • save_to_csv:将解析后的数据保存为 CSV 文件;
  • run:整合所有步骤,执行爬虫主流程。

4.2 核心代码说明

  1. 请求头设置:使用fake-useragent生成随机 User-Agent,模拟不同浏览器,降低被反爬识别的概率;
  2. 异常处理:捕获RequestException异常,处理请求超时、连接失败等问题;
  3. 数据解析:通过find_all定位视频项标签,再通过find提取每个标签内的具体字段,添加异常捕获避免单条数据解析失败导致程序终止;
  4. 数据存储:使用csv库将数据保存为 UTF-8-sig 编码的 CSV 文件,确保中文在 Excel 中正常显示。

五、输出结果展示

5.1 控制台输出

运行代码后,控制台会输出爬取进度和最终结果,示例如下:

plaintext

开始爬取B站热门视频数据...
已爬取:【全程高能】2025年度最佳混剪,这才是真正的视觉盛宴! - 影视剪辑君
已爬取:Python从入门到精通,100天全教程(附源码) - 编程学习站
已爬取:2025新款手机横评,华为/苹果/小米谁更值得买? - 数码测评师
...
数据保存完成!共爬取100条热门视频数据,文件名为:bilibili_hot_videos.csv
爬虫执行完毕!

5.2 CSV 文件输出(部分数据)

标题 UP 主 播放量 弹幕数 点赞数 时长 视频链接
【全程高能】2025 年度最佳混剪,这才是真正的视觉盛宴! 影视剪辑君 123.5 万 8923 5.6 万 08:45 https://www.bilibili.com/video/BV1234567890/
Python 从入门到精通,100 天全教程(附源码) 编程学习站 89.8 万 6789 4.2 万 12:30 https://www.bilibili.com/video/BV0987654321/
2025 新款手机横评,华为 / 苹果 / 小米谁更值得买? 数码测评师 76.3 万 5432 3.8 万 15:20 https://www.bilibili.com/video/BV1122334455/

六、注意事项与优化建议

6.1 合规性说明

  • 本爬虫仅用于学习和研究,爬取的数据不得用于商业用途;
  • 遵守 B 站的用户协议和 robots 协议(https://www.bilibili.com/robots.txt);
  • 控制爬取频率,避免给 B 站服务器造成压力。

6.2 优化方向

  1. 多线程 / 异步爬取:使用threadingaiohttp提高爬取效率(注意控制并发数);
  2. 数据去重:添加数据去重逻辑,避免重复爬取同一视频;
  3. 增量爬取:记录已爬取视频的 ID,仅爬取新增的热门视频;
  4. 数据可视化:使用pandas+matplotlib对爬取的数据进行可视化分析;
  5. 代理 IP 池:若爬取量较大,可配置代理 IP 池,进一步降低被封禁的风险。

七、常见问题解决

7.1 请求被拒绝(403 Forbidden)

  • 原因:User-Agent 被识别为爬虫,或请求频率过高;
  • 解决:更换 User-Agent,增加请求间隔,或添加更多请求头(如 Cookie)。

7.2 数据解析为空

  • 原因:B 站页面结构更新,标签类名或路径变化;
  • 解决:重新审查页面元素,更新解析时的标签定位规则。

7.3 CSV 文件中文乱码

  • 原因:编码格式不正确;
  • 解决:使用utf-8-sig编码保存 CSV 文件(代码中已实现)。

总结

  1. 爬取 B 站热门视频数据的核心流程为:构造合法请求→获取页面数据→解析 HTML→提取目标信息→存储数据;
  2. 规避反爬的关键在于模拟浏览器请求(随机 User-Agent)、控制请求频率、做好异常处理;
  3. 本文提供的代码完整可运行,爬取的数据可直接用于后续的数据分析,同时代码结构具备可扩展性,可根据需求调整解析字段和存储方式。

通过本文的学习,你不仅能掌握 B 站热门视频数据的爬取方法,也能理解 Python 爬虫的核心原理和通用开发思路,为后续爬取知乎、酷狗音乐、豆瓣等平台的数据打下基础。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐