文章目录
前言(必看!!!)
最近好多小伙伴私信问怎么用Python爬取B站视频数据(特别是弹幕和评论数据),今天就给大家安排上!不过要提前说明三点:
- 本文仅供学习交流(划重点)
- 实际应用请遵守B站robots.txt协议
- 建议使用代理IP避免被封(后面会教具体方法)
一、环境准备篇
需要安装的库(建议用清华镜像源)
pip install requests beautifulsoup4 selenium pyquery fake-useragent
推荐开发工具
- VS Code + Jupyter插件(调试神器)
- Chrome浏览器 + XPath Helper插件(定位元素超方便)
- Postman(接口调试必备)
二、网页结构分析(关键步骤!)
以这个视频为例:https://www.bilibili.com/video/BV1GJ411x7h7
按F12打开开发者工具会发现:
- 视频数据通过XHR动态加载
- 真实视频地址加密在
window.__playinfo__
- 弹幕数据接口是
https://api.bilibili.com/x/v1/dm/list.so
(超级重要)建议先通过Postman测试接口:
GET https://api.bilibili.com/x/web-interface/view?bvid=BV1GJ411x7h7
三、完整爬虫代码(含注释)
import requests
from fake_useragent import UserAgent
def get_bvid_info(bvid):
headers = {
'User-Agent': UserAgent().random,
'Referer': f'https://www.bilibili.com/video/{bvid}'
}
# 主接口(含播放量/点赞等数据)
api_url = f'https://api.bilibili.com/x/web-interface/view?bvid={bvid}'
# 使用代理(推荐穿云代理)
proxies = {
'http': 'http://xxx.xxx.xxx:xxxx',
'https': 'http://xxx.xxx.xxx:xxxx'
}
try:
response = requests.get(api_url, headers=headers, proxies=proxies)
data = response.json()['data']
# 提取关键信息
video_info = {
'标题': data['title'],
'UP主': data['owner']['name'],
'播放量': data['stat']['view'],
'弹幕数': data['stat']['danmaku'],
'收藏量': data['stat']['favorite'],
'发布时间': data['pubdate']
}
return video_info
except Exception as e:
print(f'抓取失败!错误信息:{e}')
return None
# 使用示例
print(get_bvid_info('BV1GJ411x7h7'))
四、反爬虫破解技巧(实战经验)
1. 请求头伪装
- 随机User-Agent(fake-useragent库)
- 必须携带Referer
- 建议添加Cookie(需要定期更新)
2. IP限制解决方案
推荐使用动态代理池(自建或购买服务),这里分享个免费代理获取技巧:
def get_free_proxy():
url = 'https://www.zdaye.com/free/'
# 解析网页获取代理IP(自己实现解析逻辑)
return proxy_list
3. 验证码应对策略
遇到验证码时,可以:
- 降低请求频率(time.sleep随机3-5秒)
- 使用打码平台(推荐超级鹰)
- 切换登录态Cookie
五、数据存储方案
1. CSV存储(适合新手)
import csv
with open('bilibili.csv', 'a', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=video_info.keys())
writer.writerow(video_info)
2. MySQL存储(推荐方案)
CREATE TABLE bilibili_video (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
up主 VARCHAR(100),
播放量 INT,
弹幕数 INT,
收藏量 INT,
发布时间 DATETIME
);
3. MongoDB存储(适合非结构化数据)
from pymongo import MongoClient
client = MongoClient('mongodb://localhost:27017/')
db = client['bilibili']
collection = db['videos']
collection.insert_one(video_info)
六、数据可视化示例
用matplotlib生成播放量趋势图:
import matplotlib.pyplot as plt
# 假设data是多个视频数据的列表
views = [d['播放量'] for d in data]
titles = [d['标题'][:10]+'...' for d in data]
plt.figure(figsize=(12,6))
plt.barh(titles, views, color='#00a1d6')
plt.title('B站视频播放量对比')
plt.xlabel('播放量(万)')
plt.grid(axis='x', linestyle='--')
plt.show()
七、常见问题Q&A
Q:为什么返回的数据是乱码?
A:需要设置response.encoding = 'utf-8'
Q:如何获取弹幕数据?
A:弹幕接口是https://api.bilibili.com/x/v1/dm/list.so?oid=xxx
,其中oid需要从视频接口获取
Q:会被封IP吗?
A:高频访问肯定会!建议控制频率在1次/5秒,且使用代理池
总结与建议
通过这个案例我们可以学到:
- 现代网站多用接口传输数据 ✅
- 反爬措施越来越复杂 😅
- 合法合规是前提(划重点)❗
建议新手从公开API入手练习,比如B站官方提供的开放平台API(需要申请权限)。后续可以尝试结合selenium做动态渲染页面的抓取,记得关注我的GitHub,下期我们讲《如何用Scrapy分布式爬取百万级数据》!