写一个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 相关文章推荐
python3编写C/S网络程序实例教程
Aug 25 Python
在Django框架中编写Contact表单的教程
Jul 17 Python
python中zip()方法应用实例分析
Apr 16 Python
教大家玩转Python字符串处理的七种技巧
Mar 31 Python
Python3实现将本地JSON大数据文件写入MySQL数据库的方法
Jun 13 Python
python启动应用程序和终止应用程序的方法
Jun 28 Python
django admin 自定义替换change页面模板的方法
Aug 23 Python
python使用openCV遍历文件夹里所有视频文件并保存成图片
Jan 14 Python
python torch.utils.data.DataLoader使用方法
Apr 02 Python
浅谈python opencv对图像颜色通道进行加减操作溢出
Jun 03 Python
如何设置PyCharm中的Python代码模版(推荐)
Nov 20 Python
Python3利用openpyxl读写Excel文件的方法实例
Feb 03 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 pthreads多线程的安装与使用
2016/01/19 PHP
JS操作XML中DTD介绍及使用方法分析
2019/07/04 PHP
Docker 安装 PHP并与Nginx的部署实例讲解
2021/02/27 PHP
ExtJS自定义主题(theme)样式详解
2013/11/18 Javascript
解决checkbox的attr(checked)一直为undefined问题
2014/06/16 Javascript
node.js [superAgent] 请求使用示例
2015/03/13 Javascript
利用jquery获取select下拉框的值
2016/11/23 Javascript
详解js中==与===的区别
2017/01/08 Javascript
JavaScript轮播图简单制作方法
2017/02/20 Javascript
angularjs+bootstrap菜单的使用示例代码
2017/03/07 Javascript
使用node.js实现微信小程序实时聊天功能
2018/08/13 Javascript
vue打开其他项目页面并传入数据详解
2020/11/25 Vue.js
Python Tkinter基础控件用法
2014/09/03 Python
详解Python中break语句的用法
2015/05/14 Python
Python正则表达式实现截取成对括号的方法
2017/01/06 Python
基于并发服务器几种实现方法(总结)
2017/12/29 Python
python中的turtle库函数简单使用教程
2018/07/23 Python
面向初学者的Python编辑器Mu
2018/10/08 Python
python爬虫之urllib,伪装,超时设置,异常处理的方法
2018/12/19 Python
Pycharm之快速定位到某行快捷键的方法
2019/01/20 Python
pycharm修改file type方式
2019/11/19 Python
详解Python3 定义一个跨越多行的字符串的多种方法
2020/09/06 Python
分享CSS3中必须要知道的10个顶级命令
2012/04/26 HTML / CSS
html5的自定义data-*属性与jquery的data()方法的使用
2014/07/02 HTML / CSS
const char*, char const*, char*const的区别是什么
2014/07/09 面试题
高中生的自我评价
2014/03/04 职场文书
如何写自我评价?自我评价写什么好?
2014/03/14 职场文书
委托公证书
2014/04/08 职场文书
工商行政管理专业求职书
2014/05/23 职场文书
学雷锋宣传标语
2014/06/25 职场文书
党员群众路线个人整改措施思想汇报
2014/10/12 职场文书
党员违纪检讨书
2015/05/05 职场文书
如何用Laravel包含你自己的帮助函数
2021/05/27 PHP
一篇文章弄清楚Ajax请求的五个步骤
2022/03/17 Javascript
进行数据处理的6个 Python 代码块分享
2022/04/06 Python
pnpm对npm及yarn降维打击详解
2022/08/05 Javascript