1. 为什么选择Http请求抓取B站数据做数据分析的朋友们应该都遇到过这样的困扰想要批量获取B站视频的播放量、弹幕数等数据但手动一个个页面查看效率实在太低。我之前尝试过用影刀RPA的图形化操作来采集发现虽然入门简单但在处理大量数据时速度明显跟不上。后来改用Http请求直接获取数据效率直接提升了10倍不止。Http请求的本质就是模拟浏览器向服务器发送请求。比如你在B站搜索Python教程浏览器会向B站服务器发送一个包含搜索关键词的Http请求服务器返回搜索结果页面。我们完全可以用代码模拟这个过程直接获取原始数据省去渲染页面的开销。这里有个实际案例我帮一个做教育内容分析的朋友采集了1000个编程教学视频的数据。用传统RPA方式花了3小时改用Http请求后只需要15分钟。更重要的是Http请求获取的是结构化数据后续处理起来特别方便。2. 环境准备与基础配置2.1 安装必要的Python库工欲善其事必先利其器。我们需要两个核心库requests发送Http请求的利器BeautifulSoup解析HTML的神器安装命令很简单pip install requests beautifulsoup4我建议创建一个虚拟环境来管理依赖python -m venv bilibili_env source bilibili_env/bin/activate # Linux/Mac bilibili_env\Scripts\activate # Windows2.2 配置请求头信息B站会对频繁的请求做限制所以我们需要伪装成普通浏览器。关键是要设置好User-Agentheaders { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36, Accept-Language: zh-CN,zh;q0.9, }实测发现加上Accept-Language能显著降低被拦截的概率。如果要做大规模采集建议再添加Referer和Cookie字段。3. 实现B站视频搜索功能3.1 构建搜索请求B站的搜索接口其实很有规律我们来看一个实际的搜索URLhttps://search.bilibili.com/all?keywordPython教程page1可以拆解出几个关键参数keyword搜索关键词page页码search_source搜索来源可选我封装了一个搜索函数支持多页采集def search_bilibili(keyword, pages1): videos [] for page in range(1, pages 1): url fhttps://search.bilibili.com/all?keyword{keyword}page{page} response requests.get(url, headersheaders) soup BeautifulSoup(response.text, html.parser) # 解析逻辑... return videos3.2 解析搜索结果页面B站的搜索结果页面结构经常变化所以解析逻辑要足够健壮。最新版的页面中视频卡片是这样组织的div classvideo-list row div classvideo-item.../div div classvideo-item.../div /div我建议用CSS选择器来定位元素比正则表达式更稳定video_items soup.select(.video-list .video-item) for item in video_items: title item.select_one(.title).get(title) link item.select_one(a).get(href) # 处理相对链接 if not link.startswith(http): link https: link4. 获取视频详细数据4.1 访问视频详情页拿到视频链接后我们需要进一步获取播放量等详细数据。这里有个坑要注意B站的移动端页面和PC端页面结构完全不同。建议统一使用PC端页面数据更完整。请求详情页的代码和搜索类似def get_video_detail(video_url): response requests.get(video_url, headersheaders) soup BeautifulSoup(response.text, html.parser) # 解析逻辑...4.2 解析关键数据指标视频详情页的数据分布在不同的DOM节点中。经过多次测试我发现最稳定的定位方式是使用属性选择器data { 播放量: soup.select_one([classview-text]).text, 弹幕数: soup.select_one([classdm-text]).text, 发布时间: soup.select_one([classpubdate-text]).text, 点赞数: soup.select_one([classlike-info]).text, # 其他数据... }对于数字类型的数据记得做清洗处理def clean_number(text): return int(text.replace(万, 0000).replace(,, ))5. 与影刀RPA集成实现自动化5.1 将Python代码封装为RPA模块影刀RPA支持调用Python脚本我们可以把前面的功能封装成模块# bilibili_tool.py def search_videos(keyword, pages1): # 实现搜索功能... def get_video_stats(url): # 实现详情获取...然后在影刀中用Python脚本节点调用import bilibili_tool results bilibili_tool.search_videos(Python教程)5.2 设计自动化流程一个完整的采集流程可以这样设计从Excel读取关键词列表对每个关键词执行搜索获取前N页的视频基础信息对每个视频获取详细数据将结果保存到数据库或Excel影刀的流程设计器可以直观地搭建这个流程配合Python脚本处理复杂逻辑。6. 性能优化与反反爬策略6.1 请求频率控制B站对频繁请求很敏感我建议每个请求间隔2-5秒使用随机间隔避免规律性限制并发请求数可以用time.sleep实现基础控制import time import random time.sleep(2 random.random() * 3) # 2-5秒随机间隔6.2 代理IP与请求轮换如果需要大规模采集建议使用代理IP池。一个简单的实现proxies [ {http: http://proxy1:port}, {http: http://proxy2:port}, ] proxy random.choice(proxies) requests.get(url, headersheaders, proxiesproxy)7. 数据处理与分析实战7.1 数据清洗与标准化原始数据往往需要清洗统一单位如1.2万转成12000处理空值格式转换字符串转日期def clean_data(raw_data): # 处理播放量 if 万 in raw_data[播放量]: raw_data[播放量] float(raw_data[播放量].replace(万, )) * 10000 # 转换发布时间 raw_data[发布时间] pd.to_datetime(raw_data[发布时间]) return raw_data7.2 基础数据分析示例用pandas可以快速实现一些分析import pandas as pd df pd.DataFrame(data_list) # 播放量Top10 top10 df.sort_values(播放量, ascendingFalse).head(10) # 各分区视频数量 category_count df[分区].value_counts()8. 常见问题与解决方案8.1 请求被拦截怎么办如果遇到403错误可以尝试更新User-Agent添加Referer头使用浏览器获取最新Cookie降低请求频率8.2 数据解析失败怎么处理页面结构变化是常见问题建议添加try-catch块处理异常使用更宽松的选择器定期检查脚本是否可用try: view_count soup.select_one(.view-count).text except AttributeError: view_count N/A9. 进阶技巧直接调用B站API除了解析HTMLB站其实有一些公开API可以直接调用。比如这个获取视频信息的APIhttps://api.bilibili.com/x/web-interface/view?bvidBV1xx411x7xx使用API能获得更结构化的数据但需要注意需要处理sign校验有频率限制接口可能变更我通常会把HTML解析和API调用结合使用互为备份方案。
影刀RPA | 利用Http请求高效抓取B站视频数据:从搜索到播放量分析
1. 为什么选择Http请求抓取B站数据做数据分析的朋友们应该都遇到过这样的困扰想要批量获取B站视频的播放量、弹幕数等数据但手动一个个页面查看效率实在太低。我之前尝试过用影刀RPA的图形化操作来采集发现虽然入门简单但在处理大量数据时速度明显跟不上。后来改用Http请求直接获取数据效率直接提升了10倍不止。Http请求的本质就是模拟浏览器向服务器发送请求。比如你在B站搜索Python教程浏览器会向B站服务器发送一个包含搜索关键词的Http请求服务器返回搜索结果页面。我们完全可以用代码模拟这个过程直接获取原始数据省去渲染页面的开销。这里有个实际案例我帮一个做教育内容分析的朋友采集了1000个编程教学视频的数据。用传统RPA方式花了3小时改用Http请求后只需要15分钟。更重要的是Http请求获取的是结构化数据后续处理起来特别方便。2. 环境准备与基础配置2.1 安装必要的Python库工欲善其事必先利其器。我们需要两个核心库requests发送Http请求的利器BeautifulSoup解析HTML的神器安装命令很简单pip install requests beautifulsoup4我建议创建一个虚拟环境来管理依赖python -m venv bilibili_env source bilibili_env/bin/activate # Linux/Mac bilibili_env\Scripts\activate # Windows2.2 配置请求头信息B站会对频繁的请求做限制所以我们需要伪装成普通浏览器。关键是要设置好User-Agentheaders { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36, Accept-Language: zh-CN,zh;q0.9, }实测发现加上Accept-Language能显著降低被拦截的概率。如果要做大规模采集建议再添加Referer和Cookie字段。3. 实现B站视频搜索功能3.1 构建搜索请求B站的搜索接口其实很有规律我们来看一个实际的搜索URLhttps://search.bilibili.com/all?keywordPython教程page1可以拆解出几个关键参数keyword搜索关键词page页码search_source搜索来源可选我封装了一个搜索函数支持多页采集def search_bilibili(keyword, pages1): videos [] for page in range(1, pages 1): url fhttps://search.bilibili.com/all?keyword{keyword}page{page} response requests.get(url, headersheaders) soup BeautifulSoup(response.text, html.parser) # 解析逻辑... return videos3.2 解析搜索结果页面B站的搜索结果页面结构经常变化所以解析逻辑要足够健壮。最新版的页面中视频卡片是这样组织的div classvideo-list row div classvideo-item.../div div classvideo-item.../div /div我建议用CSS选择器来定位元素比正则表达式更稳定video_items soup.select(.video-list .video-item) for item in video_items: title item.select_one(.title).get(title) link item.select_one(a).get(href) # 处理相对链接 if not link.startswith(http): link https: link4. 获取视频详细数据4.1 访问视频详情页拿到视频链接后我们需要进一步获取播放量等详细数据。这里有个坑要注意B站的移动端页面和PC端页面结构完全不同。建议统一使用PC端页面数据更完整。请求详情页的代码和搜索类似def get_video_detail(video_url): response requests.get(video_url, headersheaders) soup BeautifulSoup(response.text, html.parser) # 解析逻辑...4.2 解析关键数据指标视频详情页的数据分布在不同的DOM节点中。经过多次测试我发现最稳定的定位方式是使用属性选择器data { 播放量: soup.select_one([classview-text]).text, 弹幕数: soup.select_one([classdm-text]).text, 发布时间: soup.select_one([classpubdate-text]).text, 点赞数: soup.select_one([classlike-info]).text, # 其他数据... }对于数字类型的数据记得做清洗处理def clean_number(text): return int(text.replace(万, 0000).replace(,, ))5. 与影刀RPA集成实现自动化5.1 将Python代码封装为RPA模块影刀RPA支持调用Python脚本我们可以把前面的功能封装成模块# bilibili_tool.py def search_videos(keyword, pages1): # 实现搜索功能... def get_video_stats(url): # 实现详情获取...然后在影刀中用Python脚本节点调用import bilibili_tool results bilibili_tool.search_videos(Python教程)5.2 设计自动化流程一个完整的采集流程可以这样设计从Excel读取关键词列表对每个关键词执行搜索获取前N页的视频基础信息对每个视频获取详细数据将结果保存到数据库或Excel影刀的流程设计器可以直观地搭建这个流程配合Python脚本处理复杂逻辑。6. 性能优化与反反爬策略6.1 请求频率控制B站对频繁请求很敏感我建议每个请求间隔2-5秒使用随机间隔避免规律性限制并发请求数可以用time.sleep实现基础控制import time import random time.sleep(2 random.random() * 3) # 2-5秒随机间隔6.2 代理IP与请求轮换如果需要大规模采集建议使用代理IP池。一个简单的实现proxies [ {http: http://proxy1:port}, {http: http://proxy2:port}, ] proxy random.choice(proxies) requests.get(url, headersheaders, proxiesproxy)7. 数据处理与分析实战7.1 数据清洗与标准化原始数据往往需要清洗统一单位如1.2万转成12000处理空值格式转换字符串转日期def clean_data(raw_data): # 处理播放量 if 万 in raw_data[播放量]: raw_data[播放量] float(raw_data[播放量].replace(万, )) * 10000 # 转换发布时间 raw_data[发布时间] pd.to_datetime(raw_data[发布时间]) return raw_data7.2 基础数据分析示例用pandas可以快速实现一些分析import pandas as pd df pd.DataFrame(data_list) # 播放量Top10 top10 df.sort_values(播放量, ascendingFalse).head(10) # 各分区视频数量 category_count df[分区].value_counts()8. 常见问题与解决方案8.1 请求被拦截怎么办如果遇到403错误可以尝试更新User-Agent添加Referer头使用浏览器获取最新Cookie降低请求频率8.2 数据解析失败怎么处理页面结构变化是常见问题建议添加try-catch块处理异常使用更宽松的选择器定期检查脚本是否可用try: view_count soup.select_one(.view-count).text except AttributeError: view_count N/A9. 进阶技巧直接调用B站API除了解析HTMLB站其实有一些公开API可以直接调用。比如这个获取视频信息的APIhttps://api.bilibili.com/x/web-interface/view?bvidBV1xx411x7xx使用API能获得更结构化的数据但需要注意需要处理sign校验有频率限制接口可能变更我通常会把HTML解析和API调用结合使用互为备份方案。