Python 爬虫实战:爬取 B 站热门视频数据(附完整源码)
本文详细介绍使用Python爬取B站热门视频数据的方法,包含环境准备、核心原理、完整代码实现及优化建议。通过requests库发送HTTP请求,BeautifulSoup解析HTML提取视频标题、UP主、播放量等关键信息,最终存储为CSV文件。代码采用随机User-Agent和请求间隔规避反爬机制,适合爬虫初学者学习实践。文章还提供常见问题解决方案,强调遵守robots协议,仅用于学习研究目的。该


大会时间: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 核心代码说明
- 请求头设置:使用
fake-useragent生成随机 User-Agent,模拟不同浏览器,降低被反爬识别的概率; - 异常处理:捕获
RequestException异常,处理请求超时、连接失败等问题; - 数据解析:通过
find_all定位视频项标签,再通过find提取每个标签内的具体字段,添加异常捕获避免单条数据解析失败导致程序终止; - 数据存储:使用
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 优化方向
- 多线程 / 异步爬取:使用
threading或aiohttp提高爬取效率(注意控制并发数); - 数据去重:添加数据去重逻辑,避免重复爬取同一视频;
- 增量爬取:记录已爬取视频的 ID,仅爬取新增的热门视频;
- 数据可视化:使用
pandas+matplotlib对爬取的数据进行可视化分析; - 代理 IP 池:若爬取量较大,可配置代理 IP 池,进一步降低被封禁的风险。
七、常见问题解决
7.1 请求被拒绝(403 Forbidden)
- 原因:User-Agent 被识别为爬虫,或请求频率过高;
- 解决:更换 User-Agent,增加请求间隔,或添加更多请求头(如 Cookie)。
7.2 数据解析为空
- 原因:B 站页面结构更新,标签类名或路径变化;
- 解决:重新审查页面元素,更新解析时的标签定位规则。
7.3 CSV 文件中文乱码
- 原因:编码格式不正确;
- 解决:使用
utf-8-sig编码保存 CSV 文件(代码中已实现)。
总结
- 爬取 B 站热门视频数据的核心流程为:构造合法请求→获取页面数据→解析 HTML→提取目标信息→存储数据;
- 规避反爬的关键在于模拟浏览器请求(随机 User-Agent)、控制请求频率、做好异常处理;
- 本文提供的代码完整可运行,爬取的数据可直接用于后续的数据分析,同时代码结构具备可扩展性,可根据需求调整解析字段和存储方式。
通过本文的学习,你不仅能掌握 B 站热门视频数据的爬取方法,也能理解 Python 爬虫的核心原理和通用开发思路,为后续爬取知乎、酷狗音乐、豆瓣等平台的数据打下基础。

更多推荐



所有评论(0)