python 爬取B站原视频的实例代码


Posted in Python onSeptember 09, 2020

B站原视频爬取,我就不多说直接上代码。直接运行就好。
B站是把视频和音频分开。要把2个合并起来使用。这个需要分析才能看出来。然后就是登陆这块是比较难的。

import os
import re
import argparse
import subprocess
import prettytable
from DecryptLogin import login


'''B站类'''
class Bilibili():
	def __init__(self, username, password, **kwargs):
		self.username = username
		self.password = password
		self.session = Bilibili.login(username, password)
		self.headers = {
						'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36'
					}
		self.user_info_url = 'http://api.bilibili.com/x/space/acc/info'
		self.submit_videos_url = 'http://space.bilibili.com/ajax/member/getSubmitVideos'
		self.view_url = 'http://api.bilibili.com/x/web-interface/view'
		self.video_player_url = 'http://api.bilibili.com/x/player/playurl'
	'''运行主程序'''
	def run(self):
		while True:
			userid = input('请输入目标用户ID(例:345993405)(我的一个LOL好友凯撒可以关注他一下 谢谢) ——> ')
			user_info = self.__getUserInfo(userid)
			tb = prettytable.PrettyTable()
			tb.field_names = list(user_info.keys())
			tb.add_row(list(user_info.values()))
			print('获取的用户信息如下:')
			print(tb)
			is_download = input('是否下载该用户的所有视频(y/n, 默认: y) ——> ')
			if is_download == 'y' or is_download == 'yes' or not is_download:
				self.__downloadVideos(userid)
	'''根据userid获得该用户基本信息'''
	def __getUserInfo(self, userid):
		params = {'mid': userid, 'jsonp': 'jsonp'}
		res = self.session.get(self.user_info_url, params=params, headers=self.headers)
		res_json = res.json()
		user_info = {
						'用户名': res_json['data']['name'],
						'性别': res_json['data']['sex'],
						'个性签名': res_json['data']['sign'],
						'用户等级': res_json['data']['level'],
						'生日': res_json['data']['birthday']
					}
		return user_info
	'''下载目标用户的所有视频'''
	def __downloadVideos(self, userid):
		if not os.path.exists(userid):
			os.mkdir(userid)
		# 非会员用户只能下载到高清1080P
		quality = [('16', '流畅 360P'),
				  ('32', '清晰 480P'),
				  ('64', '高清 720P'),
				  ('74', '高清 720P60'),
				  ('80', '高清 1080P'),
				  ('112', '高清 1080P+'),
				  ('116', '高清 1080P60')][-3]
		# 获得用户的视频基本信息
		video_info = {'aids': [], 'cid_parts': [], 'titles': [], 'links': [], 'down_flags': []}
		params = {'mid': userid, 'pagesize': 30, 'tid': 0, 'page': 1, 'order': 'pubdate'}
		while True:
			res = self.session.get(self.submit_videos_url, headers=self.headers, params=params)
			res_json = res.json()
			for item in res_json['data']['vlist']:
				video_info['aids'].append(item['aid'])
			if len(video_info['aids']) < int(res_json['data']['count']):
				params['page'] += 1
			else:
				break
		for aid in video_info['aids']:
			params = {'aid': aid}
			res = self.session.get(self.view_url, headers=self.headers, params=params)
			cid_part = []
			for page in res.json()['data']['pages']:
				cid_part.append([page['cid'], page['part']])
			video_info['cid_parts'].append(cid_part)
			title = res.json()['data']['title']
			title = re.sub(r"[‘'\/\\\:\*\?\"\<\>\|\s']", ' ', title)
			video_info['titles'].append(title)
		print('共获取到用户ID<%s>的<%d>个视频...' % (userid, len(video_info['titles'])))
		for idx in range(len(video_info['titles'])):
			aid = video_info['aids'][idx]
			cid_part = video_info['cid_parts'][idx]
			link = []
			down_flag = False
			for cid, part in cid_part:
				params = {'avid': aid, 'cid': cid, 'qn': quality, 'otype': 'json', 'fnver': 0, 'fnval': 16}
				res = self.session.get(self.video_player_url, params=params, headers=self.headers)
				res_json = res.json()
				if 'dash' in res_json['data']:
					down_flag = True
					v, a = res_json['data']['dash']['video'][0], res_json['data']['dash']['audio'][0]
					link_v = [v['baseUrl']]
					link_a = [a['baseUrl']]
					if v['backup_url']:
						for item in v['backup_url']:
							link_v.append(item)
					if a['backup_url']:
						for item in a['backup_url']:
							link_a.append(item)
					link = [link_v, link_a]
				else:
					link = [res_json['data']['durl'][-1]['url']]
					if res_json['data']['durl'][-1]['backup_url']:
						for item in res_json['data']['durl'][-1]['backup_url']:
							link.append(item)
				video_info['links'].append(link)
				video_info['down_flags'].append(down_flag)
		# 开始下载
		out_pipe_quiet = subprocess.PIPE
		out_pipe = None
		aria2c_path = os.path.join(os.getcwd(), 'tools/aria2c')
		ffmpeg_path = os.path.join(os.getcwd(), 'tools/ffmpeg')
		for idx in range(len(video_info['titles'])):
			title = video_info['titles'][idx]
			aid = video_info['aids'][idx]
			down_flag = video_info['down_flags'][idx]
			print('正在下载视频<%s>...' % title)
			if down_flag:
				link_v, link_a = video_info['links'][idx]
				# --视频
				url = '"{}"'.format('" "'.join(link_v))
				command = '{} -c -k 1M -x {} -d "{}" -o "{}" --referer="https://www.bilibili.com/video/av{}" {} {}'
				command = command.format(aria2c_path, len(link_v), userid, title+'.flv', aid, "", url)
				print(command)
				process = subprocess.Popen(command, stdout=out_pipe, stderr=out_pipe, shell=True)
				process.wait()
				# --音频
				url = '"{}"'.format('" "'.join(link_a))
				command = '{} -c -k 1M -x {} -d "{}" -o "{}" --referer="https://www.bilibili.com/video/av{}" {} {}'
				command = command.format(aria2c_path, len(link_v), userid, title+'.aac', aid, "", url)
				print(command)

				process = subprocess.Popen(command, stdout=out_pipe, stderr=out_pipe, shell=True)
				process.wait()
				# --合并
				command = '{} -i "{}" -i "{}" -c copy -f mp4 -y "{}"'
				command = command.format(ffmpeg_path, os.path.join(userid, title+'.flv'), os.path.join(userid, title+'.aac'), os.path.join(userid, title+'.mp4'))
				print(command)

				process = subprocess.Popen(command, stdout=out_pipe, stderr=out_pipe_quiet, shell=True)
				process.wait()
				os.remove(os.path.join(userid, title+'.flv'))
				os.remove(os.path.join(userid, title+'.aac'))
			else:
				link = video_info['links'][idx]
				url = '"{}"'.format('" "'.join(link))
				command = '{} -c -k 1M -x {} -d "{}" -o "{}" --referer="https://www.bilibili.com/video/av{}" {} {}'
				command = command.format(aria2c_path, len(link), userid, title+'.flv', aid, "", url)
				process = subprocess.Popen(command, stdout=out_pipe, stderr=out_pipe, shell=True)
				process.wait()
				os.rename(os.path.join(userid, title+'.flv'), os.path.join(userid, title+'.mp4'))
		print('所有视频下载完成, 该用户所有视频保存在<%s>文件夹中...' % (userid))
	'''借助大佬开源的库来登录B站'''
	@staticmethod
	def login(username, password):
		_, session = login.Login().bilibili(username, password)
		return session


'''run'''
if __name__ == '__main__':
	parser = argparse.ArgumentParser(description='下载B站指定用户的所有视频(仅支持Windows下使用)')
	parser.add_argument('--username', dest='username', help='xxx', type=str, required=True)
	parser.add_argument('--password', dest='password', help='xxxx', type=str, required=True)
	print(parser)
	args = parser.parse_args(['--password', 'xxxx','--username', 'xxx'])
	# args = parser.parse_args(['--password', 'FOO'])
	print('5')
	bili = Bilibili(args.username, args.password)
	bili.run()

把账号密码填上就行。这是我根据一个微信公众号Charles大佬的想法写的。大家可以去关注他一下。

以上就是python 爬取B站原视频的实例代码的详细内容,更多关于python 爬取B站原视频的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python的函数嵌套的使用方法
Jan 24 Python
wxPython中listbox用法实例详解
Jun 01 Python
Python中内置的日志模块logging用法详解
Jul 12 Python
windows10系统中安装python3.x+scrapy教程
Nov 08 Python
numpy使用技巧之数组过滤实例代码
Feb 03 Python
利用Python进行数据可视化常见的9种方法!超实用!
Jul 11 Python
Django uwsgi Nginx 的生产环境部署详解
Feb 02 Python
python pygame实现球球大作战
Nov 25 Python
Python读取csv文件实例解析
Dec 30 Python
基于Tensorflow读取MNIST数据集时网络超时的解决方式
Jun 22 Python
Python2.x与3​​.x版本有哪些区别
Jul 09 Python
手把手教你怎么用Python实现zip文件密码的破解
May 27 Python
利用Python实现Json序列化库的方法步骤
Sep 09 #Python
python之语音识别speech模块
Sep 09 #Python
python speech模块的使用方法
Sep 09 #Python
python计算auc的方法
Sep 09 #Python
详解anaconda离线安装pytorchGPU版
Sep 08 #Python
python如何将图片转换素描画
Sep 08 #Python
Python自动化之UnitTest框架实战记录
Sep 08 #Python
You might like
写一段简单的PHP建立文件夹代码
2015/01/06 PHP
php实现递归与无限分类的方法
2015/02/16 PHP
PHP函数shuffle()取数组若干个随机元素的方法分析
2016/04/02 PHP
Google排名中的10个最著名的 JavaScript库
2010/04/27 Javascript
JavaScript中setUTCMilliseconds()方法的使用详解
2015/06/12 Javascript
javascript实现连续赋值
2015/08/10 Javascript
详解jQuery中基本的动画方法
2016/12/14 Javascript
bootstrap Validator 模态框、jsp、表单验证 Ajax提交功能
2017/02/17 Javascript
d3.js实现立体柱图的方法详解
2017/04/28 Javascript
AngularJS 限定$scope的范围实例详解
2017/06/23 Javascript
使用Vue开发动态刷新Echarts组件的教程详解
2018/03/22 Javascript
JQuery通过后台获取数据遍历到前台的方法
2018/08/13 jQuery
JavaScript日期工具类DateUtils定义与用法示例
2018/09/03 Javascript
Swiper.js实现移动端元素左右滑动
2019/09/08 Javascript
jQuery 选择器用法实例分析【prev + next】
2020/05/22 jQuery
JS highcharts动态柱状图原理及实现
2020/10/16 Javascript
python 正则式使用心得
2009/05/07 Python
Python 用户登录验证的小例子
2013/03/06 Python
使用Python的PEAK来适配协议的教程
2015/04/14 Python
使用Python求解最大公约数的实现方法
2015/08/20 Python
python机器学习实战之最近邻kNN分类器
2017/12/20 Python
Python延时操作实现方法示例
2018/08/14 Python
python获取本机所有IP地址的方法
2018/12/26 Python
python+selenium实现QQ邮箱自动发送功能
2019/01/23 Python
Python实现 版本号对比功能的实例代码
2019/04/18 Python
使用pytorch搭建AlexNet操作(微调预训练模型及手动搭建)
2020/01/18 Python
jupyternotebook 撤销删除的操作方式
2020/04/17 Python
PythonPC客户端自动化实现原理(pywinauto)
2020/05/28 Python
彻底解决Python包下载慢问题
2020/11/15 Python
Django权限控制的使用
2021/01/07 Python
新西兰演唱会和体育门票网站:Ticketmaster新西兰
2017/10/07 全球购物
日本最大的药妆连锁店:Matsukiyo松本清药妆店
2017/11/23 全球购物
介绍一下Linux内核的排队自旋锁
2014/08/27 面试题
如何写辞职书
2015/02/26 职场文书
党员干部学法用法心得体会
2016/01/21 职场文书
Javascript中Microtask和Macrotask鲜为人知的知识点
2022/04/02 Javascript