写一个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实现对一个完整url进行分割的方法
Apr 29 Python
Python实现树的先序、中序、后序排序算法示例
Jun 23 Python
简述Python2与Python3的不同点
Jan 21 Python
Python实现的用户登录系统功能示例
Feb 05 Python
python pygame实现挡板弹球游戏
Nov 25 Python
Pytorch: 自定义网络层实例
Jan 07 Python
使用tensorflow实现矩阵分解方式
Feb 07 Python
Python学习之os模块及用法
Jun 03 Python
python中有帮助函数吗
Jun 19 Python
selenium与xpath之获取指定位置的元素的实现
Jan 26 Python
pandas中DataFrame检测重复值的实现
May 26 Python
python中mongodb包操作数据库
Apr 19 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
新的一年,新的期待:DC在2020年的四部动画电影
2020/01/01 欧美动漫
PHP sprintf() 函数的应用(定义和用法)
2012/06/29 PHP
goto语法在PHP中的使用教程
2020/09/17 PHP
js通过googleAIP翻译PHP系统的语言配置的实现代码
2011/10/17 Javascript
js判断undefined类型,undefined,null, 的区别详细解析
2013/12/16 Javascript
Get中文乱码IE浏览器Get中文乱码解决方案
2013/12/26 Javascript
JS实现根据出生年月计算年龄
2014/01/10 Javascript
删除节点的jquery代码
2014/01/13 Javascript
原生js仿jq判断当前浏览器是否为ie,精确到ie6~8
2014/08/30 Javascript
JavaScript函数模式详解
2014/11/07 Javascript
javascript框架设计之浏览器的嗅探和特征侦测
2015/06/23 Javascript
JavaScript实现对下拉列表值进行排序的方法
2015/07/15 Javascript
深入浅析JS是按值传递还是按引用传递(推荐)
2016/09/18 Javascript
JS封装的三级联动菜单(使用时只需要一行js代码)
2016/10/24 Javascript
Angular.js与node.js项目里用cookie校验账户登录详解
2017/02/22 Javascript
jQuery滚动插件scrollable.js用法分析
2017/05/25 jQuery
js中split()方法得到的数组长度问题
2018/07/19 Javascript
通过vue手动封装on、emit、off的代码详解
2019/05/29 Javascript
微信小程序bindtap事件与冒泡阻止详解
2019/08/08 Javascript
JavaScript事件委托实现原理及优点进行
2020/08/29 Javascript
Python实现爬取知乎神回复简单爬虫代码分享
2015/01/04 Python
python使用xpath中遇到:到底是什么?
2018/01/04 Python
python selenium 对浏览器标签页进行关闭和切换的方法
2018/05/21 Python
修改默认的pip版本为对应python2.7的方法
2018/11/06 Python
在Python中如何传递任意数量的实参的示例代码
2019/03/21 Python
Python实现的服务器示例小结【单进程、多进程、多线程、非阻塞式】
2019/05/23 Python
基于Python获取照片的GPS位置信息
2020/01/20 Python
解决python多线程报错:AttributeError: Can't pickle local object问题
2020/04/08 Python
Pycharm新手使用教程(图文详解)
2020/09/17 Python
python des,aes,rsa加解密的实现
2021/01/16 Python
经典的班主任推荐信
2013/10/28 职场文书
电子商务专业自我鉴定
2013/12/18 职场文书
最新茶叶店创业计划书
2014/01/14 职场文书
2015年暑期社会实践活动总结
2015/03/27 职场文书
Redis安装启动及常见数据类型
2021/04/14 Redis
python实现自定义日志的具体方法
2021/05/28 Python