写一个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随机生成指定长度密码的方法
Apr 04 Python
python中self原理实例分析
Apr 30 Python
python去除所有html标签的方法
May 05 Python
Python字符串匹配算法KMP实例
Jul 18 Python
一步步教你用Python实现2048小游戏
Jan 19 Python
利用Django内置的认证视图实现用户密码重置功能详解
Nov 24 Python
深入理解Python中range和xrange的区别
Nov 26 Python
python和opencv实现抠图
Jul 18 Python
Python Opencv任意形状目标检测并绘制框图
Jul 23 Python
浅谈PyTorch的可重复性问题(如何使实验结果可复现)
Feb 20 Python
python - asyncio异步编程
Apr 06 Python
如何使用python包中的sched事件调度器
Apr 30 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+ajax 无刷新删除数据
2010/02/20 PHP
php+mysql删除指定编号员工信息的方法
2015/01/14 PHP
JavaScript实现删除电脑的关机键
2016/07/26 PHP
php输出控制函数和输出函数生成静态页面
2019/06/27 PHP
jQuery实现的Email中的收件人效果(按del键删除)
2011/03/20 Javascript
jQuery EasyUI API 中文文档 DateTimeBox日期时间框
2011/10/16 Javascript
javascript动画对象支持加速、减速、缓入、缓出的实现代码
2012/09/30 Javascript
jQuery随便控制任意div隐藏的方法
2013/06/28 Javascript
Node.js实现Excel转JSON
2015/04/24 Javascript
jQuery-1.9.1源码分析系列(十)事件系统之事件包装
2015/11/20 Javascript
基于jQuery Ajax实现上传文件
2016/03/24 Javascript
javascript设计模式之策略模式学习笔记
2017/02/15 Javascript
详解Angular 4.x 动态创建组件
2017/04/25 Javascript
Angular5升级RxJS到5.5.3报错:EmptyError: no elements in sequence的解决方法
2018/04/09 Javascript
使用Vue自定义指令实现Select组件
2018/05/24 Javascript
Nodejs文件上传、监听上传进度的代码
2020/03/27 NodeJs
Vue 数据绑定的原理分析
2020/11/16 Javascript
[01:02:48]2018DOTA2亚洲邀请赛 4.1 小组赛 A组 LGD vs OG
2018/04/02 DOTA
[01:02:04]EG vs Liquid 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.23
2019/09/05 DOTA
详谈在flask中使用jsonify和json.dumps的区别
2018/03/26 Python
Python 3.6打包成EXE可执行程序的实现
2019/10/18 Python
python实现画循环圆
2019/11/23 Python
pytorch载入预训练模型后,实现训练指定层
2020/01/06 Python
Python Opencv中用compareHist函数进行直方图比较对比图片
2020/04/07 Python
Pytorch实现WGAN用于动漫头像生成
2021/03/04 Python
Banana Republic英国官网:香蕉共和国,GAP集团旗下偏贵族风
2018/04/24 全球购物
旅游与酒店管理的自我评价分享
2013/11/03 职场文书
应届护士推荐信
2013/11/16 职场文书
大学四年职业生涯规划书范文
2014/01/02 职场文书
网络编辑岗位职责
2014/03/18 职场文书
大学团日活动新闻稿
2014/09/10 职场文书
投标文件签署授权委托书范本
2014/10/12 职场文书
刑事辩护授权委托书范本
2014/10/17 职场文书
2014年团支部工作总结
2014/11/17 职场文书
详解MySQL连接挂死的原因
2021/05/18 MySQL
mysql数据库如何转移到oracle
2022/12/24 MySQL