专栏首页python学习教程python 爬取B站原视频的实例代码

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

这篇文章主要介绍了python 爬取B站原视频的实例代码,帮助大家更好的理解和使用python 爬虫,感兴趣的朋友可以了解下

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教程(pythonjc),作者:小雨

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-09-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • python爬虫教程:批量抓取 QQ 群信息

    本文讲解Python批量抓取 QQ 群信息,包括群名称、群号、群人数、群主、地域、分类、标签、群简介等内容,返回 XLS / CSV / JSON 结果文件。

    python学习教程
  • 手把手教你用Python开发“剪刀石头布”小游戏【附源码】

    最近在学习PyQt5可视化界面,这是一个内容非常丰富的gui库,相对于tkinter库,功能更加强大,界面更加美观,操作也不难。于是我开始小试牛刀,用PyQt...

    python学习教程
  • Python用16行代码就搞定了爬取豆瓣读书页面

    我们一直说Python比较简单,代码体量没有别的程序那么大,对于初学者,尤其是零编程基础的初学者来说,感触没有那么明显,那么今天就让你见识一下:爬取豆瓣读书页面...

    python学习教程
  • python B站原视频爬取

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

    崔笑颜
  • SAP ABAP实用技巧介绍系列之利用RTTC给DDIC structure动态添加新的field

    例如需要给DDIC structure COMM_PRODUCT在runtime时添加新的field ‘FIELD3’, 类型为int. Source cod...

    Jerry Wang
  • 【Android】Walle多渠道打包&Tinker热修复

    Gavin-ZYX
  • 使用PyTorch从理论到实践理解变分自编码器VAE

    而VAE背后的关键点在于:为了从样本空间中找到能够生成合适输出的样本(就是能输出尽可能接近我们所规定分布的数据),它并没有试图去直接构造一个隐藏空间(隐藏变量所...

    deephub
  • 将复杂查询写到SQL配置文件--SOD框架的SQL-MAP技术简介

    引言 今天看到一片热门的博客, .NET高级工程师面试题之SQL篇 ,要求找出每一个系的最高分,并且按系编号,学生编号升序排列。这个查询比较复杂,也比较典型,自...

    用户1177503
  • Veeam Backup & Replication(二):添加虚拟化主机和配置备份存储

    一、添加虚拟化主机 veeam可以添加单个ESXi主机,也可以添加vCenter服务器,因为做实验,就添加一台ESXI主机为例吧。 1.1 选择 Virtual...

    行 者
  • python中if及if-else如何使用

    根据 PEP 8 标准,比较运算符两侧应该各有一个空格,比如:5 == 3。 PEP8 标准

    砸漏

扫码关注云+社区

领取腾讯云代金券