写一个Python脚本下载哔哩哔哩舞蹈区的所有视频


Posted in Python onMay 31, 2021

一、抓取列表

首先点开舞蹈区先选择宅舞列表。

写一个Python脚本下载哔哩哔哩舞蹈区的所有视频

然后打开 F12 的控制面板,可以找到一条 https://api.bilibili.com/x/web-interface/newlist?rid=20&type=0&pn=1&ps=20&jsonp=jsonp&callback=jsonCallback_bili_57905715749828263 的 url,其中 rid 是 B 站的小分类,pn 是页数。

写一个Python脚本下载哔哩哔哩舞蹈区的所有视频

小编试着在浏览器将地址打开居然报了 404,可是在控制面板中这个地址的返回值明明就是视频列表。试着去掉 callback 的参数,意外的得到了想要的结果。

写一个Python脚本下载哔哩哔哩舞蹈区的所有视频

众所周知 bid 是一个 B 站视频的唯一 ID,想要获取 bid 可以从上面 url 的返回值中提取 aid,然后将 aid 转换为 bid。

Str = 'fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF'  # 准备的一串指定字符串
Dict = {}
 
# 将字符串的每一个字符放入字典一一对应 , 如 f对应0 Z对应1 一次类推。
for i in range(58):
    Dict[Str[i]] = i
 
s = [11, 10, 3, 8, 4, 6, 2, 9, 5, 7]  # 必要的解密列表
xor = 177451812 
add = 100618342136696320  # 这串数字最后要被减去或加上
 
def algorithm_enc(av):
    ret = av
    av = int(av)
    av = (av ^ xor) + add
    # 将BV号的格式(BV + 10个字符) 转化成列表方便后面的操作
    r = list('BV          ')
    for i in range(10):
        r[s[i]] = Str[av // 58 ** i % 58]
    return ''.join(r)
 
 
def find_bid(p):
    bids = []
    r = requests.get(
            'https://api.bilibili.com/x/web-interface/newlist?&rid=20&type=0&pn={}&ps=50&jsonp=jsonp'.format(p))
      
    data = json.loads(r.text)
    archives = data['data']['archives']
 
    for item in archives:
        aid = item['aid']
        bid = algorithm_enc(aid)
        bids.append(bid)
 
    return bids

二、获取视频的 CID

想要下载 1080 的视频,光有 bid 是不够的,还需要 登录后 Cookie 中的 SESSDATA 值和 cid 。

首先登录 B 站将 Cookie 中的 SESSDATA 复制到对象头中。用地址为 https://api.bilibili.com/x/player/pagelist?bvid= url 返回 cid。

def get_cid(bid):
    url = 'https://api.bilibili.com/x/player/pagelist?bvid=' + bid
 
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
        'Cookie': 'SESSDATA=182cd036%2C1636985829%2C3b393%2A51',
        'Host': 'api.bilibili.com'
    }
 
    html = requests.get(url, headers=headers).json()
 
    infos = []
 
    data = html['data']
    cid_list = data
    for item in cid_list:
        cid = item['cid']
        title = item['part']
        infos.append({'bid': bid, 'cid': cid, 'title': title})
    return infos

三、下载视频

下载视频的 https://api.bilibili.com/x/player/playurl 来自于每次视频播放完之后的推荐列表。

写一个Python脚本下载哔哩哔哩舞蹈区的所有视频

最后使用 urllib.request.urlretrieve 函数下载视频。

def get_video_list(aid, cid, quality):
    url_api = 'https://api.bilibili.com/x/player/playurl?cid={}&bvid={}&qn={}'.format(cid, aid, quality)
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
        'Cookie': 'SESSDATA=182cd036%2C1636985829%2C3b393%2A51',
        'Host': 'api.bilibili.com'
    }
    html = requests.get(url_api, headers=headers).json()
    video_list = []
 
    for i in html['data']['durl']:
        video_list.append(i['url'])
    return video_list
 
def schedule_cmd(blocknum, blocksize, totalsize):
    percent = 100.0 * blocknum * blocksize/ totalsize
    s = ('#' * round(percent)).ljust(100, '-')
    sys.stdout.write('%.2f%%' % percent + '[' + s + ']' + '\r')
    sys.stdout.flush()
 
def download(video_list, title, bid):
    for i in video_list:
        opener = urllib.request.build_opener()
        opener.addheaders = [
            ('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36'),
            ('Accept', '*/*'),
            ('Accept-Language', 'en-US,en;q=0.5'),
            ('Accept-Encoding', 'gzip, deflate, br'), 
            ('Range', 'bytes=0-'),  
            ('Referer', 'https://www.bilibili.com/video/'+bid),
            ('Origin', 'https://www.bilibili.com'),
            ('Connection', 'keep-alive'),
 
        ]
 
        filename=os.path.join('D:\\video', r'{}_{}.mp4'.format(bid,title)) 
 
        try:
            urllib.request.install_opener(opener)
            urllib.request.urlretrieve(url=i, filename=filename, reporthook=schedule_cmd) 
        except:
            print(bid + "下载异常,文件:" + filename)

到此这篇关于写一个Python脚本下载哔哩哔哩舞蹈区的所有视频的文章就介绍到这了,更多相关python下载哔哩哔哩视频内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
浅析Python的Django框架中的Memcached
Jul 23 Python
Python 列表(List) 的三种遍历方法实例 详解
Apr 15 Python
Python实现自动为照片添加日期并分类的方法
Sep 30 Python
快速了解Python开发中的cookie及简单代码示例
Jan 17 Python
python自动12306抢票软件实现代码
Feb 24 Python
分析python动态规划的递归、非递归实现
Mar 04 Python
Python unittest模块用法实例分析
May 25 Python
解决pycharm remote deployment 配置的问题
Jun 27 Python
python pyqtgraph 保存图片到本地的实例
Mar 14 Python
Tensorflow tf.tile()的用法实例分析
May 22 Python
python如何写出表白程序
Jun 01 Python
python解析照片拍摄时间进行图片整理
Jul 23 Python
python中的plt.cm.Paired用法说明
May 31 #Python
在pycharm中无法import所安装的库解决方案
如何在pycharm中快捷安装pip命令(如pygame)
Python 实现绘制子图及子图刻度的变换等问题
python 利用PyAutoGUI快速构建自动化操作脚本
pandas中DataFrame数据合并连接(merge、join、concat)
Pandas加速代码之避免使用for循环
You might like
dede全站URL静态化改造[070414更正]
2007/04/17 PHP
php获取目标函数执行时间示例
2014/03/04 PHP
ThinkPHP模板Switch标签用法示例
2014/06/30 PHP
php中session与cookie的比较
2015/01/27 PHP
PHP多进程之pcntl_fork的实例详解
2017/10/15 PHP
php和asp语法上的区别总结
2019/05/12 PHP
Javascript 读书笔记索引贴
2010/01/11 Javascript
关于setInterval、setTimeout在jQuery中的使用注意事项
2011/09/28 Javascript
33个优秀的 jQuery 图片展示插件分享
2012/03/14 Javascript
window.parent与window.openner区别介绍
2012/04/12 Javascript
js 输出内容到新窗口具体实现代码
2013/05/31 Javascript
实现只能输入数字的input不用replace方法
2013/09/12 Javascript
IE与FF下javascript获取网页及窗口大小的区别详解
2014/01/14 Javascript
JavaScript返回当前会话cookie全部键值对照的方法
2015/04/03 Javascript
jquery代码实现简单的随机图片瀑布流效果
2015/04/20 Javascript
Jquery实现顶部弹出框特效
2015/08/08 Javascript
jQuery UI设置固定日期选择特效代码分享
2015/08/27 Javascript
JavaScript html5 canvas绘制时钟效果(二)
2016/03/27 Javascript
基于jQuery实现中英文切换导航条效果
2016/09/18 Javascript
Angular.JS学习之依赖注入$injector详析
2016/10/20 Javascript
js实现增加数字显示的环形进度条效果
2017/02/05 Javascript
深入浅析Node环境和浏览器的区别
2018/08/14 Javascript
通过实例讲解JS如何防抖动
2019/06/15 Javascript
[01:39:42]Fnatic vs Mineski 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
Python获取Windows或Linux主机名称通用函数分享
2014/11/22 Python
Python实现图像几何变换
2015/07/06 Python
Python实现TCP协议下的端口映射功能的脚本程序示例
2016/06/14 Python
Python 逐行分割大txt文件的方法
2017/10/10 Python
python编程实现12306的一个小爬虫实例
2017/12/27 Python
Python基本socket通信控制操作示例
2019/01/30 Python
详解python中的三种命令行模块(sys.argv,argparse,click)
2020/12/15 Python
使用OpenCV实现人脸图像卡通化的示例代码
2021/01/15 Python
全球领先的全景影像品牌:Insta360
2019/08/21 全球购物
香港演唱会订票网站:StubHub香港
2019/10/10 全球购物
领导视察欢迎词
2014/01/15 职场文书
Python Pandas pandas.read_sql函数实例用法
2021/06/21 Python