python下载b站视频_爬虫可以当是一个批量下载工具!用Python批量下载B站视频
说起B站,肯定人人都知道吧,B站的反扒机制并不是太严格,所以今天我准备给大家说说我能想到的几种方式,目前大概想到了三种方式:
1、模拟手机端请求,视频链接就添加在源码中。(最简单、但清晰度不好)
2、通过调用别人的接口来下载视频。(根据接口的破解难度而定,可选择清晰度)
3、直接通过B站的网页版来抓取。(难度稍大)
那么接下来我就来依次给大家介绍介绍我的方法!
分析与主要代码:
既然方法一已经确定是模拟手机端的方式去请求,那么我们就直接开始分析:
对该链接进行抓包,找了半天,并没有找到什么有用的信息,所以我就直接去查看网页源码:
在仔细地查看源码后,就发现了如上所示的信息,视频的
MP4链接和视频名就加载在源码之中。
因为这些信息都储存在
标签中,虽然能够将所有内容提取出来,再转换为 JSON 格式进行提取,但是这样的话就显得有些麻烦了,我们直接用正则表达式来提取:
代码
class BiLiBiLi_phone():
def __init__(self,s_url):
self.url=s_url
self.headers={
'origin': 'https://m.bilibili.com',
'referer': self.url,
'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N)'
}
def bili_Download(self):
r = requests.get(self.url, proxies=proxy, headers=self.headers)
video_name=re.findall(',"title":"(.*?)","pubdate":', r.text)[0]
if video_name == '':
video_name = int(random.random() * 2 * 1000)
if len(str(video_name)) > 20:
video_name = video_name[:20]
video_url = re.findall(',"url":"(.*?)","backup_url"', r.text)[0].encode('utf-8').decode('unicode_escape')
r=requests.get(video_url,proxies=proxy,headers=self.headers)
with open(path+video_name+'.mp4','wb')as f:
f.write(r.content)
print("【BiLiBiLi】: {} 下载完成!".format(video_name))
关于代码的一些注解:
video_url = re.findall(’,“url”:"(.*?)",“backup_url”’, r.text)[0].encode(‘utf-8’).decode(‘unicode_escape’)
标黄字体之前的代码为正则表达式的基本操作,而标黄的字体的原因是:
从源码中提取的到的链接为:
http:\u002F\u002Fupos-sz-mirrorkodo.bilivideo.com\u002Fupgcxcode\u002F10\u002F14\u002F230501410\u002F230501410-1-16.mp4?e=ig8euxZM2rNcNbdlhoNvNC8BqJIzNbfq9rVEuxTEnE8L5F6VnEsSTx0vkX8fqJeYTj_lta53NCM=&uipk=5&nbs=1&deadline=1601216024&gen=playurl&os=kodobv&oi=1971851232&trid=fcde238782674b78bf4425427c2a9ea3h&platform=html5&upsig=b98cc40700e7f05e614acf0acbd9b671&uparams=e,uipk,nbs,deadline,gen,os,oi,trid,platform&mid=262968904&logo=80000000
链接中包含了大量的\u002F字段,这是因为源码中加载的是转换为 Unicode 编码后的链接,所以要进行编码转化。
分析与主要代码:
对于方法二,我们首先需要找到一个第三方的网站来解析视频,然后将整个过程进行包装。
不同的网站有不同的解析方式,我这里只写出我随便选择的一个网站,清晰度就还行吧。
介于这个网站的特殊性:当输入链接为:
https://www.bilibili.com/video/BV1R54y1e7J3?spm_id_from=333.5.b_646f7567615f6d6164.4时会出现以下报错
所以需要将后面的部分信息去掉!
将准备好的链接放到解析网站可以得到以下信息:
由于网站的特殊性,若选取
MP4文件 ,有时会出现视频分成多个的情况,所以我在这里主要选取 FLV文件。
我们可以很清楚的看到,该接口返回的内容中,是一些属于
HTML标签 的信息,在这里不编写清晰度选择的代码,有需要的可以自行编写,直接选取清晰度最好的一个来解析。
代码
这是为了防止这个 B 站视频解析服务网站被滥用。在这里我对该解析网站进行了隐藏,想要使用这个解析服务的地址,可以私信我。
这种解析网站的一种特点就是,知道的人越多,它失效的也就越快。
希望这样,它可以尽量活得久一点点。
class BiLiBiLi_api():
def __init__(self, s_url):
self.url = s_url.split('?')[0]
self.header1 = {
'Host': 'www.****.com',
'Origin': 'http://www.****.com',
'Referer': quote('http://www.****.com/video?url={}&page=video&submit=视频下载'.format(self.url)),
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 Edg/85.0.564.63'
}
self.data = {
'url': self.url,
'format': 'flv',
'from': 'parse',
'retry': '1'
}
self.header2 = {
'origin': 'https://www.bilibili.com/',
'referer': self.url,
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 Edg/85.0.564.63'
}
def BL_api_Download(self):
r = requests.post('http://www.****.com/parse', proxies=proxy, data=self.data, headers=self.header1)
video_name = re.findall('data-clipboard-text="(.*?)"', r.json()['msg'])[0]
video_url = re.findall('href="(.*?)"', r.json()['msg'])[0].replace('amp;', '')
r1 = requests.get(video_url, proxies=proxy, headers=self.header2)
with open(path + video_name + '.flv', 'wb')as f:
f.write(r1.content)
print("【BiLiBiLi】: {} 下载完成!".format(video_name))
关于代码的一些注解:
初始化中为什么含有两个请求头信息。
1、header1的请求头信息为解析网站时所需要的一些信息。
2、header2的请求头信息为下载视频时所需要的一些信息。
请求头为什么要分开写成两个:
第一个请求头所需的信息就不用多说,都是常规操作。第二个请求头所需是信息时因为该网站所解析出的视频链接为B站中的原链接,所以要带上关于B站信息的请求头来进行下载,否则服务器将会拒绝 我们访问。
data数据是什么:
在上述解析网站的操作过程中我们还记得,在请求完解析链接后,仍然需要选择视频文件的格式,我们才能得到视频的链接,而当我们选择完格式以后,会再次对原链接进行请求,并且会携带上固定格式的data数据。
quote(‘http://www.****.com/video?url={}&page=video&submit=视频下载’.format(self.url))
为什么要进行编码转换:
网站就是这样,不更换编码,它要报错,嘿嘿嘿。
video_url = re.findall(‘href="(.*?)"’, r.json()[‘msg’])[0].replace(‘amp;’, ‘’)
同之前所说的,未标黄的部分也还是基本操作,就是利用正则表达式来提取信息,而对于所标黄的部分,这是因为所解析到的链接中含有 HTML的转移字符:
http://cn-cq-gd-bcache-15.bilivideo.com/upgcxcode/10/14/230501410/230501410-1-80.flv?e=ig8euxZM2rNcNbu1hbUVhoMahWNBhwdEto8g5X10ugNcXBlqNxHxNEVE5XREto8KqJZHUa6m5J0SqE85tZvEuENvNC8xNEVE9EKE9IMvXBvE2ENvNCImNEVEK9GVqJIwqa80WXIekXRE9IMvXBvEuENvNCImNEVEua6m2jIxux0CkF6s2JZv5x0DQJZY2F8SkXKE9IB5QK&deadline=1601220310&gen=playurl&nbs=1&oi=1696943910&os=bcache&platform=pc&trid=380e02a6015c4f6c89df5944e35a87a8&uipk=5&upsig=062c2af07c4454f8641dc7552b1c1f3e&uparams=e,deadline,gen,nbs,oi,os,platform,trid,uipk&mid=0
方法三
编写中…(遇到了点小麻烦!)
全部源码
import random
import re
from urllib.parse import quote
import requests
url = 'https://ip.jiangxianli.com/api/proxy_ip'
r = requests.get(url)
proxy = {'HTTP': 'http://' + r.json()['data']['ip'] + ':' + r.json()['data']['port']}
print(proxy)
path = 'C:/Users/Jackson-art/Desktop/'
class BiLiBiLi_phone():
def __init__(self, s_url):
self.url = s_url
self.headers = {
'origin': 'https://m.bilibili.com',
'referer': self.url,
'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N)'
}
def bili_Download(self):
r = requests.get(self.url, proxies=proxy, headers=self.headers)
video_name = re.findall(',"title":"(.*?)","pubdate":', r.text)[0]
if video_name == '':
video_name = int(random.random() * 2 * 1000)
if len(str(video_name)) > 20:
video_name = video_name[:20]
video_url = re.findall(',"url":"(.*?)","backup_url"', r.text)[0].encode('utf-8').decode('unicode_escape')
r = requests.get(video_url, proxies=proxy, headers=self.headers)
with open(path + video_name + '.mp4', 'wb')as f:
f.write(r.content)
print("【BiLiBiLi】: {} 下载完成!".format(video_name))
class BiLiBiLi_api():
def __init__(self, s_url):
self.url = s_url.split('?')[0]
self.header1 = {
'Host': 'www.****.com',
'Origin': 'http://www.****.com',
'Referer': quote('http://www.****.com/video?url={}&page=video&submit=视频下载'.format(self.url)),
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 Edg/85.0.564.63'
}
self.data = {
'url': self.url,
'format': 'flv',
'from': 'parse',
'retry': '1'
}
self.header2 = {
'origin': 'https://www.bilibili.com/',
'referer': self.url,
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 Edg/85.0.564.63'
}
def BL_api_Download(self):
r = requests.post('http://www.****.com/parse', proxies=proxy, data=self.data, headers=self.header1)
video_name = re.findall('data-clipboard-text="(.*?)"', r.json()['msg'])[0]
video_url = re.findall('href="(.*?)"', r.json()['msg'])[0].replace('amp;', '')
r1 = requests.get(video_url, proxies=proxy, headers=self.header2)
with open(path + video_name + '.flv', 'wb')as f:
f.write(r1.content)
print("【BiLiBiLi】: {} 下载完成!".format(video_name))
def user_ui():
print('*' * 10 + '\t BiLiBiLi视频下载\t' + '*' * 10)
print('*' * 5 + "\t\tAuthor: 高智商白痴\t\t" + '*' * 5)
share_url = input('请输入分享链接: ')
choice = int(input("1、模拟手机端下载 2、调用接口下载 3、直接下载\n选择下载方式:"))
if choice == 1:
BiLiBiLi_phone(share_url).bili_Download()
if choice == 2:
BiLiBiLi_api(share_url).BL_api_Download()
if choice == 3:
print("编写中。。。")
if __name__ == '__main__':
user_ui()
BIG福利
虽然这篇博客还没有写完,不过我已经迫不及待的给大家分享我在寻早资源的过程中发现的好多西:B站的壁纸
其实B站有一个官方号,上面全是一些2233娘的一些壁纸,嘿嘿嘿~
你学会了吗?
此文转载文,著作权归作者所有,如有侵权联系小编删除!
python下载b站视频_爬虫可以当是一个批量下载工具!用Python批量下载B站视频相关推荐
- python 爬取搞笑视频_爬虫篇 | 用Python爬超级搞笑的视频
最近整理一个爬虫系列方面的文章,不管大家的基础如何,我从头开始整一个爬虫系列方面的文章,让大家循序渐进的学习爬虫,小白也没有学习障碍. 这两天看到别人用Python下载视频,于是我也来试一下平时总是喜 ...
- python抓取抖音热门视频_要是30行代码!7步教会你Python爬取网页抖音热门视频
前言 抖音短视频相信大家都听过,也不陌生对吧!可以看到海量的短视频,涵盖了各大行业.个人觉得抖音有毒,刷着刷着根本停不下来,一看时间就是凌晨3.4点.今天带大家爬取抖音网页版的视频数据!一睹为快吧 本 ...
- python金融工程的工具包_《华尔街学堂:三大金融技能工具——Wind. Excel 与 Python》...
课程目录: Excel实务技能与金融应用 课时 14 课件资料 第01讲课程练习-Councils 2015_25 LTP Financial Data.xlsx 第2 & 3讲练习(1).x ...
- python做erp系统教程_“python2.7教程廖雪峰“刚开始学openERP Python,如何快速入门?...
为什么廖雪峰的JS教程不如Python 教程 娃娃哈 廖雪峰python教程在哪 这是他的网址:www.liaoxuefeng.com 这是python专有python2.7,python3,可供选择 ...
- python开发影视exe程序_搜片大师,一个不需要编程就能拥有百万影视站点的搜片神器,Python编写,Windows版界面...
这个世界太疯狂了,来北京好几个月了,都还没找到工作.俗话说,一天不编程,连hello world都写不出来.在这个"焦虑"的最后一个月,差不多每天吃馒头加山泉水,差点流落街头.可以 ...
- is在python中是什么意思_【IT专家】关键字:is和=在python中有什么区别
本文由我司收集整编,推荐下载,如有疑问,请与我司联系 关键字: is 和 = 在 python 中有什么区别 关键字: is 和 = 在 python 中有什么区别 [ 英 ]What is the ...
- 32岁了学python来的及吗_为什么每个人都应该在2020年学习Python?
如今每个人都在谈论 Python,包括那些曾经对 Python 嗤之以鼻的人.本文作者 Javinpaul 原是一名 Java 狂热粉,他以前还曾号召大家学习 Java 而不是 Python.如今他的 ...
- 战网下载CDN重定向失败_卧槽,又开源一个下载神器,利用各种平台下载任意文件...
@Travis-CI && @GithubAction && @Coding && @Vercel,你帮我下载文件行吗QvQ 前言 开源地址:https ...
- python好用的软件_【分享|10款超好用的辅助Python的软件,初学者请查收!】- 环球网校...
[摘要]在这个科学技术高速发展的时代,越来越多的人都开始选择学习编程软件,那么首先被大家选择的编程软件就是python,也用在各行各业之中,并被大家所熟知,所以也有越来越多的python学习者关注Py ...
最新文章
- c/c++中typedef与函数指针
- dm9000 driver 1
- nodejs 30行代码 爬豆瓣电影数据
- Resharper 和 Rider 的奇淫技巧,你知道多少?
- 联通光纤限制连接数_从数百万个光纤(而不是数千个线程)中查询数据库
- Docker 容器 和 虚拟机 的异同
- pthread_once()
- OpenShift 4 - DevSecOps - 视频
- 哈工大大数据实验_大数据创新实验室丨警大智慧警务学院人才培养打造新引擎...
- FTP服务学习笔记之FTP简介(1)
- 控制台没有消息循环_【干货】思科设备报错消息汇总大全~
- 【转】 sqlserver 异地备份
- 《python核心编程》笔记——系统限制
- Excel任务该如何在FineReader 12中设置
- win10使用软件提示“为了对电脑进行保护,已经阻止此应用”或软件上面有盾牌不能正常打开软件。
- RISC-V MCU+病房系统
- 量化新手初识基金绩效分析
- 【2019暑假】市中小学生游泳比赛-酱油记By Chavapa
- SpringBoot实现微信扫码登录功能让网站支持使用微信登录demo
- 南昌宠物医院-贝贝宠物医院