写一个Python脚本自动爬取Bilibili小视频


Posted in Python onApril 24, 2021

我身边的很多小伙伴们在朋友圈里面晒着出去游玩的照片,简直了,人多的不要不要的,长城被堵到水泄不通,老实人想想啊,既然人这么多,哪都不去也是件好事,没事还可以刷刷 B 站 23333 。这时候老实人也有了一个大胆地想法,能不能让这些在旅游景点排队的小伙伴们更快地打发时间呢?考虑到视频的娱乐性和大众观看量,我决定对 B 站新推出的小视频功能下手,于是我跑到B站去找API接口,果不起然,B站在小视频功能处提供了 API 接口,小伙伴们有福了哟!

写一个Python脚本自动爬取Bilibili小视频

B 站小视频网址在这里哦:

http://vc.bilibili.com/p/eden/rank#/?tab=全部

此次实验,我们爬取的是每日的小视频排行榜前 top100

我们该如何去爬取呢???

实验环境准备

  • Chrome 浏览器 (能使用开发者模式的浏览器都行)
  • Vim (编辑器任选,老实人比较喜欢Vim界面,所以才用这个啦)
  • Python3 开发环境
  • Kali Linux (其实随便一个操作系统都行啦)

API 寻找 && 提取

我们通过 F12 打开开发者模式,然后在 Networking -> Name 字段下找到这个链接:

写一个Python脚本自动爬取Bilibili小视频

我们可以看到Request URL这个属性值,我们向下滑动加载视频的过程中,发现只有这段url是不变的。

http://api.vc.bilibili.com/board/v1/ranking/top?

next_offset 会一直变化,我们可以猜测,这个可能就是获取下一个视频序号,我们只需要把这部分参数取出来,把 next_offset 写成变量值,用 JSON 的格式返回到目标网页即可。

写一个Python脚本自动爬取Bilibili小视频

代码实现

我们通过上面的尝试写了段代码,发现 B 站在一定程度上做了反爬虫操作,所以我们需要先获取 headers 信息,否则下载下来的视频是空的,然后定义 params 参数存储 JSON 数据,然后通过 requests.get 去获取其参数值信息,用 JSON 的格式返回到目标网页即可,实现代码如下:

def get_json(url):
    headers = {
        'User-Agent': 
        'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
    }

    params = {
        'page_size': 10,
        'next_offset': str(num),
        'tag': '今日热门',
        'platform': 'pc'
    }

    try:
        html = requests.get(url,params=params,headers=headers)
        return html.json()

    except BaseException:
        print('request error')
        pass

为了能够清楚的看到我们下载的情况,我们折腾了一个下载器上去,实现代码如下:

def download(url,path):
    start = time.time() # 开始时间
    size = 0
    headers = {
        'User-Agent': 
        'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
    }

    response = requests.get(url,headers=headers,stream=True) # stream属性必须带上
    chunk_size = 1024 # 每次下载的数据大小
    content_size = int(response.headers['content-length']) # 总大小
    if response.status_code == 200:
        print('[文件大小]:%0.2f MB' %(content_size / chunk_size / 1024)) # 换算单位
        with open(path,'wb') as file:
            for data in response.iter_content(chunk_size=chunk_size):
                file.write(data)
                size += len(data) # 已下载的文件大小

效果如下:

写一个Python脚本自动爬取Bilibili小视频

将上面的代码进行汇总,整个实现过程如下:

#!/usr/bin/env python
#-*-coding:utf-8-*-
import requests
import random
import time
def get_json(url):
    headers = {
        'User-Agent': 
        'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
    }

    params = {
        'page_size': 10,
        'next_offset': str(num),
        'tag': '今日热门',
        'platform': 'pc'
    }

    try:
        html = requests.get(url,params=params,headers=headers)
        return html.json()

    except BaseException:
        print('request error')
        pass

def download(url,path):
    start = time.time() # 开始时间
    size = 0
    headers = {
        'User-Agent': 
        'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
    }

    response = requests.get(url,headers=headers,stream=True) # stream属性必须带上
    chunk_size = 1024 # 每次下载的数据大小
    content_size = int(response.headers['content-length']) # 总大小
    if response.status_code == 200:
        print('[文件大小]:%0.2f MB' %(content_size / chunk_size / 1024)) # 换算单位
        with open(path,'wb') as file:
            for data in response.iter_content(chunk_size=chunk_size):
                file.write(data)
                size += len(data) # 已下载的文件大小

    

if __name__ == '__main__':
    for i in range(10):
        url = 'http://api.vc.bilibili.com/board/v1/ranking/top?'
        num = i*10 + 1
        html = get_json(url)
        infos = html['data']['items']
        for info in infos:
            title = info['item']['description'] # 小视频的标题
            video_url = info['item']['video_playurl'] # 小视频的下载链接
            print(title)

            # 为了防止有些视频没有提供下载链接的情况
            try:
                download(video_url,path='%s.mp4' %title)
                print('成功下载一个!')
                
            except BaseException:
                print('凉凉,下载失败')
                pass

        time.sleep(int(format(random.randint(2,8)))) # 设置随机等待时间

爬取效果图如下:

写一个Python脚本自动爬取Bilibili小视频

似乎爬取的效果还可以,当然喜欢的朋友不要忘记点赞分享转发哦。

项目链接

Github

以上就是写一个 Python 脚本自动爬取 Bilibili 小视频的详细内容,更多关于Python 爬取 Bilibili 小视频的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
在GitHub Pages上使用Pelican搭建博客的教程
Apr 25 Python
使用python实现ANN
Dec 20 Python
利用Python如何实现一个小说网站雏形
Nov 23 Python
PyQt5实现五子棋游戏(人机对弈)
Mar 24 Python
对python实现模板生成脚本的方法详解
Jan 30 Python
Django如何简单快速实现PUT、DELETE方法
Jul 24 Python
python matplotlib imshow热图坐标替换/映射实例
Mar 14 Python
如何基于python3和Vue实现AES数据加密
Mar 27 Python
MxNet预训练模型到Pytorch模型的转换方式
May 25 Python
python线程里哪种模块比较适合
Aug 02 Python
Python 开发工具通过 agent 代理使用的方法
Sep 27 Python
基于PyTorch实现一个简单的CNN图像分类器
May 29 Python
python实现图片批量压缩
Apr 24 #Python
如何用python绘制雷达图
两行代码解决Jupyter Notebook中文不能显示的问题
python基础详解之if循环语句
Apr 24 #Python
解决jupyter notebook图片显示模糊和保存清晰图片的操作
Jupyter notebook 输出部分显示不全的解决方案
Apr 24 #Python
Python opencv缺陷检测的实现及问题解决
You might like
PHP的explode和implode的使用说明
2011/07/17 PHP
Linux中用PHP判断程序运行状态的2个方法
2014/05/04 PHP
php禁止浏览器使用缓存页面的方法
2014/11/07 PHP
PHP获取数组长度或某个值出现次数的方法
2015/02/11 PHP
yii2.0使用Plupload实现带缩放功能的多图上传
2015/12/22 PHP
jQuery实现简单的DIV拖动效果
2016/02/19 Javascript
用jQuery获取table中行id和td值的实现代码
2016/05/19 Javascript
浅谈jquery点击label触发2次的问题
2016/06/12 Javascript
Bootstrap零基础学习第一课之模板
2016/07/18 Javascript
快速掌握jQuery插件开发
2017/01/19 Javascript
JS实现动态添加DOM节点和事件的方法示例
2017/04/28 Javascript
Node.js命令行/批处理中如何更改Linux用户密码浅析
2018/07/22 Javascript
Vue render渲染时间戳转时间,时间转时间戳及渲染进度条效果
2018/07/27 Javascript
Vue中div contenteditable 的光标定位方法
2018/08/25 Javascript
vue使用v-if v-show页面闪烁,div闪现的解决方法
2018/10/12 Javascript
element-ui多文件上传的实现示例
2019/04/10 Javascript
微信小程序事件流原理解析
2019/11/27 Javascript
详解vue修改elementUI的分页组件视图没更新问题
2020/11/13 Javascript
js实现抽奖功能
2020/11/24 Javascript
[03:42]2014DOTA2西雅图国际邀请赛 Navi战队巡礼
2014/07/07 DOTA
python解析中国天气网的天气数据
2014/03/21 Python
Python使用combinations实现排列组合的方法
2018/11/13 Python
Python 实现文件打包、上传与校验的方法
2019/02/13 Python
python中yield的用法详解——最简单,最清晰的解释
2019/04/04 Python
Python可迭代对象操作示例
2019/05/07 Python
PYQT5设置textEdit自动滚屏的方法
2019/06/14 Python
Python中list的交、并、差集获取方法示例
2019/08/01 Python
Django实现celery定时任务过程解析
2020/04/21 Python
python爬虫可以爬什么
2020/06/16 Python
英国在线药房和在线药剂师:Chemist 4 U
2020/01/05 全球购物
加拿大户外探险购物网站:SAIL
2020/06/27 全球购物
技术负责人任命书
2014/06/05 职场文书
品质标语大全
2014/06/21 职场文书
竞选班干部演讲稿100字
2014/08/20 职场文书
2015年党员个人工作总结
2015/05/13 职场文书
Python数据可视化之用Matplotlib绘制常用图形
2021/06/03 Python