写一个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 相关文章推荐
一篇不错的Python入门教程
Feb 08 Python
Python 命令行非阻塞输入的小例子
Sep 27 Python
python操作列表的函数使用代码详解
Dec 28 Python
python实现学生信息管理系统
Apr 05 Python
对python中使用requests模块参数编码的不同处理方法
May 18 Python
TensorFlow利用saver保存和提取参数的实例
Jul 26 Python
在scrapy中使用phantomJS实现异步爬取的方法
Dec 17 Python
使用Django开发简单接口实现文章增删改查
May 09 Python
python 使用递归回溯完美解决八皇后的问题
Feb 26 Python
Pytorch生成随机数Tensor的方法汇总
Sep 09 Python
Python 将代码转换为可执行文件脱离python环境运行(步骤详解)
Jan 25 Python
Python中使用Selenium环境安装的方法步骤
Feb 22 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的类树(支持无限分类)
2006/10/09 PHP
php下实现折线图效果的代码
2007/04/28 PHP
PHP 开发环境配置(测试开发环境)
2010/04/28 PHP
php getimagesize 上传图片的长度和宽度检测代码
2010/05/15 PHP
PHP 显示客户端IP与服务器IP的代码
2010/10/12 PHP
解析zend studio中直接导入svn中的项目的方法步骤
2013/06/21 PHP
使用tp框架和SQL语句查询数据表中的某字段包含某值
2019/10/18 PHP
Javascript 中的类和闭包
2010/01/08 Javascript
Javascript的构造函数和constructor属性
2010/01/09 Javascript
JavaScript获取页面中表单(form)数量的方法
2015/04/03 Javascript
Node.js的文件权限及读写flag详解
2016/10/11 Javascript
BootStrap栅格系统、表单样式与按钮样式源码解析
2017/01/20 Javascript
在javascript中,null>=0 为真,null==0却为假,null的值详解
2017/02/22 Javascript
JavaScript中document.referrer的用法详解
2017/07/04 Javascript
如何使用RoughViz可视化Vue.js中的草绘图表
2021/01/30 Vue.js
[02:09]2018DOTA2亚洲邀请赛TNC赛前采访
2018/04/04 DOTA
[56:21]LGD vs IG 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python 连连看连接算法
2008/11/22 Python
python使用mysqldb连接数据库操作方法示例详解
2013/12/03 Python
Python3 正在毁灭 Python的原因分析
2014/11/28 Python
Python中Random和Math模块学习笔记
2015/05/18 Python
Python3指定路径寻找符合匹配模式文件
2015/05/22 Python
TensorFlow的权值更新方法
2018/06/14 Python
Python multiprocess pool模块报错pickling error问题解决方法分析
2019/03/20 Python
python实现QQ空间自动点赞功能
2019/04/09 Python
Python数据分析pandas模块用法实例详解
2019/11/20 Python
使用PyCharm官方中文语言包汉化PyCharm
2020/11/18 Python
有趣、实用和鼓舞人心的产品:Inspire Uplift
2019/11/05 全球购物
单位刻章介绍信范文
2014/01/11 职场文书
民族学专业求职信
2014/07/28 职场文书
2014物价局群众路线对照检查材料思想汇报
2014/09/21 职场文书
2015年乡镇流动人口工作总结
2015/05/12 职场文书
升学宴来宾致辞
2015/07/27 职场文书
结婚主持人致辞
2015/07/28 职场文书
SpringBoot快速入门详解
2021/07/21 Java/Android
python元组打包和解包过程详解
2021/08/02 Python