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版本的读写锁操作方法
Apr 25 Python
无法使用pip命令安装python第三方库的原因及解决方法
Jun 12 Python
彻彻底底地理解Python中的编码问题
Oct 15 Python
利用Pyhton中的requests包进行网页访问测试的方法
Dec 26 Python
Python Pexpect库的简单使用方法
Jan 29 Python
Python 常用模块 re 使用方法详解
Jun 06 Python
Python使用docx模块实现刷题功能代码
Feb 13 Python
解析pip安装第三方库但PyCharm中却无法识别的问题及PyCharm安装第三方库的方法教程
Mar 10 Python
keras 获取某层输出 获取复用层的多次输出实例
May 23 Python
keras 多任务多loss实例
Jun 22 Python
python import 上级目录的导入
Nov 03 Python
Selenium Webdriver元素定位的八种常用方式(小结)
Jan 13 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 什么是PEAR?(第二篇)
2009/03/19 PHP
浅析PHP substr,mb_substr以及mb_strcut的区别和用法
2013/06/21 PHP
20个2014年最优秀的PHP框架回顾
2014/10/22 PHP
php+redis消息队列实现抢购功能
2018/02/08 PHP
Laravel5.1框架路由分组用法实例分析
2020/01/04 PHP
js中匿名函数的N种写法
2010/09/08 Javascript
HTML页面弹出居中可拖拽的自定义窗口层
2014/05/07 Javascript
Javascript中的关键字和保留字整理
2014/10/16 Javascript
js实现星星打分效果的方法
2020/07/05 Javascript
javascript实现html页面之间参数传递的四种方法实例分析
2015/12/15 Javascript
jQuery解决IE6、7、8不能使用 JSON.stringify 函数的问题
2016/05/31 Javascript
node.js Sequelize实现单实例字段或批量自增、自减
2016/12/08 Javascript
使用jsonp实现跨域获取数据实例讲解
2016/12/25 Javascript
利用JS判断客户端类型你应该知道的四种方法
2017/12/22 Javascript
关于Vue Router中路由守卫的应用及在全局导航守卫中检查元字段的方法
2018/12/09 Javascript
Node.js web 应用如何封装到Docker容器中
2020/09/01 Javascript
[22:20]初生之犊-TI4第5名LGD战队纪录片
2014/08/13 DOTA
Python作用域用法实例详解
2016/03/15 Python
python实现发送邮件及附件功能
2021/03/02 Python
Python DataFrame 设置输出不显示index(索引)值的方法
2018/06/07 Python
Python实现自定义函数的5种常见形式分析
2018/06/16 Python
python画折线图的程序
2018/07/26 Python
Django Rest framework解析器和渲染器详解
2019/07/25 Python
python的json中方法及jsonpath模块用法分析
2019/12/06 Python
python利用 keyboard 库记录键盘事件
2020/10/16 Python
Python根据URL地址下载文件并保存至对应目录的实现
2020/11/15 Python
Python爬虫简单运用爬取代理IP的实现
2020/12/01 Python
Sunglass Hut巴西网上商店:男女太阳镜
2020/10/04 全球购物
信息技术专业个人自我评价
2013/12/11 职场文书
买房委托公证书
2014/04/08 职场文书
目标责任书范本
2014/04/16 职场文书
2014年青年教师工作总结
2014/12/17 职场文书
廉洁自律承诺书2015
2015/01/22 职场文书
试用期自我评价范文
2015/03/10 职场文书
2016年校园社会综合治理宣传月活动总结
2016/03/16 职场文书
JS前端可视化canvas动画原理及其推导实现
2022/08/05 Javascript