preface

Download all the videos uploaded by the specified UP master on Site B. Without further ado, let’s begin happily

The development tools

Python version: 3.6.4
Related modules:

DecryptLogin module;

The argparse module;

And some of the modules that come with Python.

Environment set up

Install Python and add it to the environment variable, and the PIP will install the appropriate module.

Because this library is often updated now, so I did not upload it to PyPI. I will consider uploading it to PyPI after the function of this library is more perfect. The list of sites that the library currently supports mock login is as follows:

If you have any comments or suggestions about the library, you can open an issues. The link can be found here:

https://github.com/CharlesPikachu/DecryptLogin

Introduction of the principle

Here’s how it works, because Station B can only download 1080P videos when the user is logged in. So the first step is to use my open source DecryptLogin library to simulate logging in to B (after all, low-quality videos are uncomfortable to watch). This is easy to do in a few lines of code:

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

The next step is the cliche to grab a bag. Enter the homepage of an UP master:

! [figure (https://upload-images.jianshu…

First of all, let’s grab the basic information of the UP master (this information is completely unnecessary to grab all the videos of the UP master, and it is only used to determine whether the userid you input is consistent with the user you want to grab). This is very simple, refresh and find:

In a few lines of code:

Def __getUserInfo(self, userid): params = {'mid': userid, 'jsonp': 'jsonp'} res = self.session.get(self.user_info_url, params=params, Json () user_info = {' username ': res_json['data']['name'], 'gender ': Res_json [' data '] [] 'sex', 'character signature: res_json [' data'] [' sign '], 'user rating: res_json [' data'] [' level '], 'birthday' : res_json['data']['birthday'] } return user_info

Next is to download all the videos of the UP master, because it may be more time-consuming (the end of the year time is relatively short T_T), so directly go to the source code of You-get to find out if there is a ready-made API, found that the main need for the following three interfaces:

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

The first two interfaces are used to obtain the basic information of all the users’ videos. According to the information, the third interface is used to obtain the download link of the video. Finally, it is OK to download these videos by calling Aria2C. Specifically, the code implements the following:

Def __downloadVideos(self, userid): if not os.path.exists(userid): OS. The mkdir (userid) # non-members users can download the hd 1080 p quality = [(' 16 ', 'smooth 360 p), (' 32', 'clear 480 p), (' 64', 'hd 720 p), (' 74', 'hd 720 p60), (' 80', 'hd 1080 p), (' 112', 'hd 1080 p +), (' 116', 'hd 1080 p60)], [3] # user basic information of video 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']", "the title) video_info [' titles']. Append (title) : print (' access to the user ID of the < % s > < % d > a video... ' % (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 (' Download video <%s>... ' % title) if down_flag: link_v, Link_a = video_info [' links'] [independence idx] # - video url = '" {} "'. The format (' "" '. Join (link_v) command = '{} {} - c - m - 1 k x - d" {} "- o  "{}" --referer="https://www.bilibili.com/video/av{}" {} {}' command = command.format(aria2c_path, len(link_v), userid, title+'.flv', aid, "", url) process = subprocess.Popen(command, stdout=out_pipe, stderr=out_pipe, Shell = True) process. The wait () # - audio url = '" {} "'. The format (' "" '. Join (link_a) command = '{} {} - c - m - 1 k x - d" {} "-o" {}" --referer="https://www.bilibili.com/video/av{}" {} {}' command = command.format(aria2c_path, len(link_v), userid, title+'.aac', aid, "", url) process = subprocess.Popen(command, stdout=out_pipe, stderr=out_pipe, Shell = True) process. The wait () # - merge 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')) 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, Print (' All videos are downloaded, all videos are saved in <%s> folder... ' % (userid))

After reading this article like friends point a like support, pay attention to me every day to share Python simulation login series, the next article to share netease cloud personal playlist downloader

All done~ complete source code see personal profile or private message access to related files.