您好,我是@iFeng的小屋,一枚4年程序猿。

一、爬取目标

B站热门视频区是了解当前流行趋势的好地方,但手动一页页翻太慢,而且播放量、弹幕、点赞等数据要一个个点进去看,UP主的粉丝数还得另外查。想做数据分析,光靠肉眼太费劲。

爬取目标网址:https://www.bilibili.com/v/popular/all

二、展示爬取结果

话不多说,先看成果。爬取结果包含以下字段:

  • 序号、标题、链接、UP主、UP主ID、UP主粉丝数

  • 精确播放数、历史累计弹幕数、点赞数、投硬币枚数、收藏人数、转发人数、评论数

  • 发布时间、视频时长(秒)、视频简介、标签、视频aid、BV号

三、原理讲解

  1. 热门视频接口:B站热门视频有公开API:https://api.bilibili.com/x/web-interface/popular?ps=20&pn={page},返回JSON包含视频列表,每页20条。

  2. 视频详情:返回的列表中包含视频的标题、BV号、UP主ID、播放统计等基础信息。

  3. UP主粉丝数:通过另一个接口 https://api.bilibili.com/x/relation/stat?vmid={mid} 获取,返回粉丝数。

  4. 视频标签:通过接口 https://api.bilibili.com/x/tag/archive/tags?aid={aid} 获取,返回标签列表。

  5. 数据清洗:用 pandas 处理缺失值(数值填0、文本填空),并剔除时长<10秒或播放数≤0的异常记录。

三、爬虫代码讲解

导入库:

import requests
import pandas as pd
import time
import random
from datetime import datetime
3.1 核心思路与配置

爬虫封装成两个类:BilibiliDataCollector 负责采集,DataPreprocessor 负责清洗。这样结构清晰,后期维护方便。

3.2 关键步骤:获取热门视频列表
def get_popular_videos(self, pages=30):
    all_videos = []
    for page in range(1, pages + 1):
        api_url = f'https://api.bilibili.com/x/web-interface/popular?ps=20&pn={page}'
        time.sleep(random.uniform(1, 3))  # 随机延迟,避免被封
        response = requests.get(api_url, headers=self.headers)
        data = response.json()
        videos = data['data']['list']
        for video in videos:
            video_data = self.extract_video_info(video)
            if video_data:
                all_videos.append(video_data)
    return pd.DataFrame(all_videos)
3.3 关键步骤:提取视频信息
def extract_video_info(self, video, index):
    title = video.get('title', '')
    bvid = video.get('bvid', '')
    aid = video.get('aid', '')
    owner = video.get('owner', {})
    author_id = owner.get('mid', '')
    stat = video.get('stat', {})
    pubdate = video.get('pubdate', 0)
    publish_date = datetime.fromtimestamp(pubdate).strftime('%Y-%m-%d %H:%M:%S') if pubdate else '未知'

    follower_count = self.get_up_follower_count(author_id)  # 调接口查粉丝数
    tags = self.get_video_tags(aid, bvid)                   # 调接口查标签

    return {
        '序号': index,
        '标题': title,
        '链接': f'https://www.bilibili.com/video/{bvid}',
        'up主': owner.get('name', ''),
        'up主id': author_id,
        'up主粉丝数': follower_count,
        '精确播放数': stat.get('view', 0),
        '历史累计弹幕数': stat.get('danmaku', 0),
        '点赞数': stat.get('like', 0),
        '投硬币枚数': stat.get('coin', 0),
        '收藏人数': stat.get('favorite', 0),
        '转发人数': stat.get('share', 0),
        '评论数': stat.get('reply', 0),
        '发布时间': publish_date,
        '视频时长(秒)': video.get('duration', 0),
        '视频简介': video.get('desc', ''),
        '标签': tags,
        '视频aid': aid,
        'BV号': bvid
    }
3.5 数据清洗
class DataPreprocessor:
    def clean_data(self, df):
        df_cleaned = df.copy()
        numeric_columns = ['精确播放数', '历史累计弹幕数', '点赞数', ...]
        for col in numeric_columns:
            df_cleaned[col] = df_cleaned[col].fillna(0)
        text_columns = ['标题', 'up主', '视频简介', '标签']
        for col in text_columns:
            df_cleaned[col] = df_cleaned[col].fillna('')
        df_cleaned = df_cleaned[
            (df_cleaned['视频时长(秒)'] >= 10) &
            (df_cleaned['精确播放数'] > 0)
        ]
        return df_cleaned
3.6 主函数
def main():
    collector = BilibiliDataCollector()
    df_raw = collector.get_popular_videos(pages=20)  # 可修改页数
    if df_raw.empty:
        print("未获取到数据,程序结束")
        return
    # 保存原始数据
    raw_filename = f'raw_bilibili_data_{datetime.now().strftime("%Y%m%d_%H%M%S")}.csv'
    df_raw.to_csv(raw_filename, index=False, encoding='utf-8-sig')
    preprocessor = DataPreprocessor()
    df_cleaned = preprocessor.clean_data(df_raw)
    preprocessor.save_cleaned_data(df_cleaned, 'cleaned_bilibili_data.csv')

四、如何运行?

  1. 安装依赖pip install requests pandas

  2. 修改页数:在 main() 函数中修改 pages 参数(默认20)。

  3. 运行脚本:直接执行,等待爬取完成。

  4. 查看结果:当前目录下会生成 raw_bilibili_data_时间戳.csv 和 cleaned_bilibili_data.csv 两个文件。

五、说明

  1. 请求频率:代码中已加入随机延迟,但如果你爬取大量数据,建议再适当增加间隔。

  2. 接口稳定性:B站API偶尔会调整,如果发现某个字段为空,请检查代码中的键名是否需要更新。

  3. 数据清洗:清洗步骤可根据自己需求调整,比如你想保留所有数据,可以注释掉过滤部分。

  4. 完整源码:上述代码为核心模块,完整可运行的源码包含更详细的异常处理和注释,已打包整理。

需要本文完整可运行Python源码的小伙伴,我都放在了与此号同名的公众号里,大家自行获取。

持续分享Python干货中!更多爬虫源码干货,请前往主页查看~

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐