当前位置:   article > 正文

Python爬虫实战,DecryptLogin模块,Python模拟登录实现载B站指定UP主的所有视频_python 登录b站下载4k视频

python 登录b站下载4k视频

前言

下载B站上指定的UP主所上传的所有视频。废话不多说,让我们愉快地开始吧~

开发工具

** Python版本:**3.6.4

** 相关模块:**

DecryptLogin模块;

argparse模块;

以及一些python教程自带的模块。

环境搭建

安装Python并添加到环境变量,pip安装需要的相关模块即可。

原理简介

这里简单介绍一下原理吧,因为B站只有在用户登录状态下才能下载1080P的视频。所以我们首先要利用我开源的DecryptLogin库模拟登录B站(毕竟低画质的视频看着不舒服),这个很简单,几行代码就搞定了:

  1. from DecryptLogin import login
  2. _, session = login.Login().bilibili(username, password)

接下来就是老生常谈的抓包了,进入某个UP主的主页:

首先我们来抓取UP主的基本信息(抓取UP主所有的视频时完全不需要这些信息,只是用来确定你输入的userid是否和你想抓取的用户一致用的),这个很简单,刷新一下发现:

几行代码就搞定了:

  1. '''根据userid获得该用户基本信息'''
  2. def __getUserInfo(self, userid):
  3. params = {'mid': userid, 'jsonp': 'jsonp'}
  4. res = self.session.get(self.user_info_url, params=params, headers=self.headers)
  5. res_json = res.json()
  6. user_info = {
  7. '用户名': res_json['data']['name'],
  8. '性别': res_json['data']['sex'],
  9. '个性签名': res_json['data']['sign'],
  10. '用户等级': res_json['data']['level'],
  11. '生日': res_json['data']['birthday']
  12. }
  13. return user_info
'
运行

接下来就是下载该UP主的所有视频了,因为感觉搞起来可能比较费时间(年底了时间比较紧张T_T),所以就直接去you-get的源码里找了找有没有现成的API了,发现主要需要以下三个接口:

  1. 'https://space.bilibili.com/ajax/member/getSubmitVideos'
  2. 'https://api.bilibili.com/x/web-interface/view'
  3. 'https://api.bilibili.com/x/player/playurl'

第一,二个接口用来获取用户所有的视频的基本信息,根据这些信息然后再利用第三个接口来获得视频的下载链接,最后利用调用aria2c下载这些视频就OK了。具体而言,代码实现如下:

  1. '''下载目标用户的所有视频'''
  2. def __downloadVideos(self, userid):
  3. if not os.path.exists(userid):
  4. os.mkdir(userid)
  5. # 非会员用户只能下载到高清1080P
  6. quality = [('16', '流畅 360P'),
  7. ('32', '清晰 480P'),
  8. ('64', '高清 720P'),
  9. ('74', '高清 720P60'),
  10. ('80', '高清 1080P'),
  11. ('112', '高清 1080P+'),
  12. ('116', '高清 1080P60')][-3]
  13. # 获得用户的视频基本信息
  14. video_info = {'aids': [], 'cid_parts': [], 'titles': [], 'links': [], 'down_flags': []}
  15. params = {'mid': userid, 'pagesize': 30, 'tid': 0, 'page': 1, 'order': 'pubdate'}
  16. while True:
  17. res = self.session.get(self.submit_videos_url, headers=self.headers, params=params)
  18. res_json = res.json()
  19. for item in res_json['data']['vlist']:
  20. video_info['aids'].append(item['aid'])
  21. if len(video_info['aids']) < int(res_json['data']['count']):
  22. params['page'] += 1
  23. else:
  24. break
  25. for aid in video_info['aids']:
  26. params = {'aid': aid}
  27. res = self.session.get(self.view_url, headers=self.headers, params=params)
  28. cid_part = []
  29. for page in res.json()['data']['pages']:
  30. cid_part.append([page['cid'], page['part']])
  31. video_info['cid_parts'].append(cid_part)
  32. title = res.json()['data']['title']
  33. title = re.sub(r"[‘’\/\\\:\*\?\"\<\>\|\s']", ' ', title)
  34. video_info['titles'].append(title)
  35. print('共获取到用户ID<%s><%d>个视频...' % (userid, len(video_info['titles'])))
  36. for idx in range(len(video_info['titles'])):
  37. aid = video_info['aids'][idx]
  38. cid_part = video_info['cid_parts'][idx]
  39. link = []
  40. down_flag = False
  41. for cid, part in cid_part:
  42. params = {'avid': aid, 'cid': cid, 'qn': quality, 'otype': 'json', 'fnver': 0, 'fnval': 16}
  43. res = self.session.get(self.video_player_url, params=params, headers=self.headers)
  44. res_json = res.json()
  45. if 'dash' in res_json['data']:
  46. down_flag = True
  47. v, a = res_json['data']['dash']['video'][0], res_json['data']['dash']['audio'][0]
  48. link_v = [v['baseUrl']]
  49. link_a = [a['baseUrl']]
  50. if v['backup_url']:
  51. for item in v['backup_url']:
  52. link_v.append(item)
  53. if a['backup_url']:
  54. for item in a['backup_url']:
  55. link_a.append(item)
  56. link = [link_v, link_a]
  57. else:
  58. link = [res_json['data']['durl'][-1]['url']]
  59. if res_json['data']['durl'][-1]['backup_url']:
  60. for item in res_json['data']['durl'][-1]['backup_url']:
  61. link.append(item)
  62. video_info['links'].append(link)
  63. video_info['down_flags'].append(down_flag)
  64. # 开始下载
  65. out_pipe_quiet = subprocess.PIPE
  66. out_pipe = None
  67. aria2c_path = os.path.join(os.getcwd(), 'tools/aria2c')
  68. ffmpeg_path = os.path.join(os.getcwd(), 'tools/ffmpeg')
  69. for idx in range(len(video_info['titles'])):
  70. title = video_info['titles'][idx]
  71. aid = video_info['aids'][idx]
  72. down_flag = video_info['down_flags'][idx]
  73. print('正在下载视频<%s>...' % title)
  74. if down_flag:
  75. link_v, link_a = video_info['links'][idx]
  76. # --视频
  77. url = '"{}"'.format('" "'.join(link_v))
  78. command = '{} -c -k 1M -x {} -d "{}" -o "{}" --referer="https://www.bilibili.com/video/av{}" {} {}'
  79. command = command.format(aria2c_path, len(link_v), userid, title+'.flv', aid, "", url)
  80. process = subprocess.Popen(command, stdout=out_pipe, stderr=out_pipe, shell=True)
  81. process.wait()
  82. # --音频
  83. url = '"{}"'.format('" "'.join(link_a))
  84. command = '{} -c -k 1M -x {} -d "{}" -o "{}" --referer="https://www.bilibili.com/video/av{}" {} {}'
  85. command = command.format(aria2c_path, len(link_v), userid, title+'.aac', aid, "", url)
  86. process = subprocess.Popen(command, stdout=out_pipe, stderr=out_pipe, shell=True)
  87. process.wait()
  88. # --合并
  89. command = '{} -i "{}" -i "{}" -c copy -f mp4 -y "{}"'
  90. command = command.format(ffmpeg_path, os.path.join(userid, title+'.flv'), os.path.join(userid, title+'.aac'), os.path.join(userid, title+'.mp4'))
  91. process = subprocess.Popen(command, stdout=out_pipe, stderr=out_pipe_quiet, shell=True)
  92. process.wait()
  93. os.remove(os.path.join(userid, title+'.flv'))
  94. os.remove(os.path.join(userid, title+'.aac'))
  95. else:
  96. link = video_info['links'][idx]
  97. url = '"{}"'.format('" "'.join(link))
  98. command = '{} -c -k 1M -x {} -d "{}" -o "{}" --referer="https://www.bilibili.com/video/av{}" {} {}'
  99. command = command.format(aria2c_path, len(link), userid, title+'.flv', aid, "", url)
  100. process = subprocess.Popen(command, stdout=out_pipe, stderr=out_pipe, shell=True)
  101. process.wait()
  102. os.rename(os.path.join(userid, title+'.flv'), os.path.join(userid, title+'.mp4'))
  103. print('所有视频下载完成, 该用户所有视频保存在<%s>文件夹中...' % (userid))

文章到这里就结束了,感谢你的观看,下篇文章分享网易云个人歌单下载器

为了感谢读者们,我想把我最近收藏的一些编程干货分享给大家,回馈每一个读者,希望能帮到你们。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/912820
推荐阅读
相关标签
  

闽ICP备14008679号