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自然语言处理 NLTK 库用法入门教程【经典】
Jun 26 Python
Python实现点阵字体读取与转换的方法
Jan 29 Python
pyqt5利用pyqtDesigner实现登录界面
Mar 28 Python
Python识别html主要文本框过程解析
Feb 18 Python
python模拟点击网页按钮实现方法
Feb 25 Python
python GUI库图形界面开发之PyQt5信号与槽机制、自定义信号基础介绍
Feb 25 Python
python实现简单坦克大战
Mar 27 Python
Windows下Anaconda和PyCharm的安装与使用详解
Apr 23 Python
PyTorch中Tensor的数据类型和运算的使用
Sep 03 Python
Python headers请求头如何实现快速添加
Nov 03 Python
python入门教程之基本算术运算符
Nov 13 Python
教你用Python matplotlib库制作简单的动画
Jun 11 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
PHP5.0正式发布 不完全兼容PHP4 新增多项功能
2006/10/09 PHP
文件系统基本操作类
2006/11/23 PHP
PHP关联数组实现根据元素值删除元素的方法
2015/06/26 PHP
php判断邮箱地址是否存在的方法
2016/02/13 PHP
php getcwd与dirname(__FILE__)区别详解
2016/09/24 PHP
PHP 微信扫码支付源代码(推荐)
2016/11/03 PHP
基于php编程规范(详解)
2017/08/17 PHP
JavaScript去掉数组中的重复元素
2011/01/13 Javascript
解决Extjs上传图片无法预览的解决方法
2012/03/22 Javascript
jquery实现submit提交表单
2015/02/03 Javascript
js为什么不能正确处理小数运算?
2015/12/29 Javascript
整理JavaScript对DOM中各种类型的元素的常用操作
2016/05/05 Javascript
jQuery实现打开页面渐现效果示例
2016/07/27 Javascript
AngularJS入门教程引导程序
2016/08/18 Javascript
Ajax与服务器(JSON)通信实例代码
2016/11/05 Javascript
vue高德地图之玩转周边
2017/06/16 Javascript
JS分页的实现(同步与异步)
2017/09/16 Javascript
微信小程序实现图片懒加载的示例代码
2017/12/13 Javascript
微信小程序如何获取openid及用户信息
2018/01/26 Javascript
vue动态绑定组件子父组件多表单验证功能的实现代码
2018/05/14 Javascript
微信小程序收货地址API兼容低版本解决方法
2019/05/18 Javascript
微信小程序动态添加view组件的实例代码
2019/05/23 Javascript
JS查找孩子节点简单示例
2019/07/25 Javascript
p5.js临摹动态图形实现方法详解
2019/10/23 Javascript
[02:47]DOTA2英雄基础教程 野性怒吼兽王
2013/12/05 DOTA
ActiveMQ:使用Python访问ActiveMQ的方法
2019/01/30 Python
pytorch神经网络之卷积层与全连接层参数的设置方法
2019/08/18 Python
Michael Kors澳大利亚官网:世界知名的奢侈饰品和成衣设计师
2020/02/13 全球购物
新闻专业大学生找工作的自我评价
2013/10/30 职场文书
新闻系毕业生推荐信
2013/11/16 职场文书
公司同意接收函
2014/01/13 职场文书
销售合作意向书范本
2015/05/08 职场文书
心术观后感
2015/06/11 职场文书
装修公司管理制度
2015/08/05 职场文书
Pygame Time时间控制的具体使用详解
2021/11/17 Python
实战Python爬虫爬取酷我音乐
2022/04/11 Python