From 8f8153150fc26a1b0d12b884ae33bbe33c9b2d22 Mon Sep 17 00:00:00 2001 From: CharlesPikachu <1159254961@qq.com> Date: Mon, 27 Dec 2021 12:10:22 +0800 Subject: [PATCH] format code style --- examples/QQReports/generate.py | 32 +- examples/QQReports/modules/utils.py | 142 ++++---- .../downloadUserVideos.py | 302 +++++++++--------- 3 files changed, 235 insertions(+), 241 deletions(-) diff --git a/examples/QQReports/generate.py b/examples/QQReports/generate.py index 0159126..69861fe 100644 --- a/examples/QQReports/generate.py +++ b/examples/QQReports/generate.py @@ -1,10 +1,10 @@ ''' Function: - QQ个人专属报告生成 + QQ个人专属报告生成 Author: - Charles + Charles 微信公众号: - Charles的皮卡丘 + Charles的皮卡丘 ''' import warnings from modules.utils import * @@ -27,20 +27,20 @@ checkDir(RESULTS_SAVE_DIR) '''下载所有需要的数据''' def getReportsData(): - qq_reports = QQReports(DATA_SAVE_DIR) - # 个人基本信息 - personal_info = qq_reports.getPersonalInfo(PERSONAL_INFO_FILENAME+'.pkl') - makePersonalCard(personal_info, PERSONAL_INFO_BG_PATH, savepath=os.path.join(RESULTS_SAVE_DIR, PERSONAL_INFO_FILENAME+'.jpg'), fontpath=FONT_PATH) - # 好友信息 - friends_info = qq_reports.getQQFriendsInfo(FRIENDS_INFO_FILENAME+'.pkl') - nicknames = [value[0] for value in friends_info.values()] - nicknames = dict(zip(nicknames, [1]*len(nicknames))) - drawWordCloud(nicknames, savepath=os.path.join(RESULTS_SAVE_DIR, FRIENDS_INFO_FILENAME+'.jpg'), font_path=FONT_PATH) - # 最近操作信息 - recent_operation_info = qq_reports.getRecentOperationsInfo(RECENT_OPERATIONS_INFO_FILENAME+'.pkl') - makeRecentCard(friends_info, recent_operation_info, RECENT_OPERATIONS_INFO_BG_PATH, savepath=os.path.join(RESULTS_SAVE_DIR, RECENT_OPERATIONS_INFO_FILENAME+'.jpg'), fontpath=FONT_PATH) + qq_reports = QQReports(DATA_SAVE_DIR) + # 个人基本信息 + personal_info = qq_reports.getPersonalInfo(PERSONAL_INFO_FILENAME+'.pkl') + makePersonalCard(personal_info, PERSONAL_INFO_BG_PATH, savepath=os.path.join(RESULTS_SAVE_DIR, PERSONAL_INFO_FILENAME+'.jpg'), fontpath=FONT_PATH) + # 好友信息 + friends_info = qq_reports.getQQFriendsInfo(FRIENDS_INFO_FILENAME+'.pkl') + nicknames = [value[0] for value in friends_info.values()] + nicknames = dict(zip(nicknames, [1]*len(nicknames))) + drawWordCloud(nicknames, savepath=os.path.join(RESULTS_SAVE_DIR, FRIENDS_INFO_FILENAME+'.jpg'), font_path=FONT_PATH) + # 最近操作信息 + recent_operation_info = qq_reports.getRecentOperationsInfo(RECENT_OPERATIONS_INFO_FILENAME+'.pkl') + makeRecentCard(friends_info, recent_operation_info, RECENT_OPERATIONS_INFO_BG_PATH, savepath=os.path.join(RESULTS_SAVE_DIR, RECENT_OPERATIONS_INFO_FILENAME+'.jpg'), fontpath=FONT_PATH) '''run''' if __name__ == '__main__': - getReportsData() \ No newline at end of file + getReportsData() \ No newline at end of file diff --git a/examples/QQReports/modules/utils.py b/examples/QQReports/modules/utils.py index a559811..f96564a 100644 --- a/examples/QQReports/modules/utils.py +++ b/examples/QQReports/modules/utils.py @@ -1,10 +1,10 @@ ''' Function: - 定义一些工具函数 + 定义一些工具函数 Author: - Charles + Charles 微信公众号: - Charles的皮卡丘 + Charles的皮卡丘 ''' import os import pickle @@ -14,91 +14,91 @@ from PIL import Image, ImageDraw, ImageFont '''以.pkl格式保存数据''' def saveData2Pkl(data, savepath): - with open(savepath, 'wb') as f: - pickle.dump(data, f) - return True + with open(savepath, 'wb') as f: + pickle.dump(data, f) + return True '''导出.pkl格式数据''' def loadPkl(filepath): - with open(filepath, 'rb') as f: - data = pickle.load(f) - return data + with open(filepath, 'rb') as f: + data = pickle.load(f) + return data '''检测文件夹是否存在''' def checkDir(dirpath): - if not os.path.exists(dirpath): - os.mkdir(dirpath) - return False - return True + if not os.path.exists(dirpath): + os.mkdir(dirpath) + return False + return True '''利用个人基本信息制作QQ个人名片''' def makePersonalCard(personal_info, bgpath, color=(0, 0, 0), fontpath=None, fontsize=50, savepath=None): - font = ImageFont.truetype(fontpath, fontsize) - num = len(personal_info.keys()) - img = Image.open(bgpath) - width, height = img.width, img.height - draw = ImageDraw.Draw(img) - interval = (height - num * fontsize) // (num + 1) - x = 20 - y = interval * 3 - for key, value in personal_info.items(): - if key == '个性签名': - draw.text((x, y), '%s: ' % key, color, font) - y += interval - draw.text((x, y), '%s' % value, color, font) - y += interval - else: - draw.text((x, y), '%s: %s' % (key, value), color, font) - y += interval - img.save(savepath) + font = ImageFont.truetype(fontpath, fontsize) + num = len(personal_info.keys()) + img = Image.open(bgpath) + width, height = img.width, img.height + draw = ImageDraw.Draw(img) + interval = (height - num * fontsize) // (num + 1) + x = 20 + y = interval * 3 + for key, value in personal_info.items(): + if key == '个性签名': + draw.text((x, y), '%s: ' % key, color, font) + y += interval + draw.text((x, y), '%s' % value, color, font) + y += interval + else: + draw.text((x, y), '%s: %s' % (key, value), color, font) + y += interval + img.save(savepath) '''词云''' def drawWordCloud(words, savepath=None, font_path=None): - wc = WordCloud(font_path=font_path, background_color='white', max_words=2000, width=1920, height=1080, margin=5) - wc.generate_from_frequencies(words) - wc.to_file(savepath) + wc = WordCloud(font_path=font_path, background_color='white', max_words=2000, width=1920, height=1080, margin=5) + wc.generate_from_frequencies(words) + wc.to_file(savepath) '''最近的操作名片''' def makeRecentCard(friends_info, recent_operation_info, bgpath, color=(0, 0, 0), fontpath=None, fontsize=50, savepath=None): - font = ImageFont.truetype(fontpath, fontsize) - img = Image.open(bgpath) - width, height = img.width, img.height - draw = ImageDraw.Draw(img) - interval = (height - 10 * fontsize) // 11 - x = 20 - y = interval * 3 - key = '过去30天我退出的群个数' - value = recent_operation_info.get(key) - draw.text((x, y), '%s: %s' % (key, value), color, font) - y += interval - key = '过去30天我退出的群' - value = ','.join(recent_operation_info.get(key)) - draw.text((x, y), '%s: %s' % (key, value), color, font) - y += interval - key = '过去一年我删除的好友个数' - value = recent_operation_info.get(key) - draw.text((x, y), '%s: %s' % (key, value), color, font) - y += interval - key = '过去一年我删除的好友' - value = ','.join(recent_operation_info.get(key)) - draw.text((x, y), '%s: %s' % (key, value), color, font) - y += interval * 2 - key1 = '我在意谁' - key2 = '谁在意我' - value1 = recent_operation_info.get(key1) - value2 = recent_operation_info.get(key2) - x1 = 20 - x2 = width // 2 - draw.text((x1, y), '%s' % key1, color, font) - draw.text((x2, y), '%s' % key2, color, font) - y += interval - for v1, v2 in zip(value1, value2): - draw.text((x1, y), '%s, 亲密度: %s' % (friends_info[v1[0]][0], v1[1]), color, font) - draw.text((x2, y), '%s, 亲密度: %s' % (friends_info[v2[0]][0], v2[1]), color, font) - y += interval - img.save(savepath) \ No newline at end of file + font = ImageFont.truetype(fontpath, fontsize) + img = Image.open(bgpath) + width, height = img.width, img.height + draw = ImageDraw.Draw(img) + interval = (height - 10 * fontsize) // 11 + x = 20 + y = interval * 3 + key = '过去30天我退出的群个数' + value = recent_operation_info.get(key) + draw.text((x, y), '%s: %s' % (key, value), color, font) + y += interval + key = '过去30天我退出的群' + value = ','.join(recent_operation_info.get(key)) + draw.text((x, y), '%s: %s' % (key, value), color, font) + y += interval + key = '过去一年我删除的好友个数' + value = recent_operation_info.get(key) + draw.text((x, y), '%s: %s' % (key, value), color, font) + y += interval + key = '过去一年我删除的好友' + value = ','.join(recent_operation_info.get(key)) + draw.text((x, y), '%s: %s' % (key, value), color, font) + y += interval * 2 + key1 = '我在意谁' + key2 = '谁在意我' + value1 = recent_operation_info.get(key1) + value2 = recent_operation_info.get(key2) + x1 = 20 + x2 = width // 2 + draw.text((x1, y), '%s' % key1, color, font) + draw.text((x2, y), '%s' % key2, color, font) + y += interval + for v1, v2 in zip(value1, value2): + draw.text((x1, y), '%s, 亲密度: %s' % (friends_info[v1[0]][0], v1[1]), color, font) + draw.text((x2, y), '%s, 亲密度: %s' % (friends_info[v2[0]][0], v2[1]), color, font) + y += interval + img.save(savepath) \ No newline at end of file diff --git a/examples/bilibiliDownloadUserVideos/downloadUserVideos.py b/examples/bilibiliDownloadUserVideos/downloadUserVideos.py index 3280ade..af72b70 100644 --- a/examples/bilibiliDownloadUserVideos/downloadUserVideos.py +++ b/examples/bilibiliDownloadUserVideos/downloadUserVideos.py @@ -1,10 +1,10 @@ ''' Function: - 获得指定用户信息并下载该用户所有视频 + 获得指定用户信息并下载该用户所有视频 Author: - Charles + Charles 微信公众号: - Charles的皮卡丘 + Charles的皮卡丘 ''' import os import re @@ -16,158 +16,152 @@ 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 = 'https://api.bilibili.com/x/space/acc/info' - self.submit_videos_url = 'https://space.bilibili.com/ajax/member/getSubmitVideos' - self.view_url = 'https://api.bilibili.com/x/web-interface/view' - self.video_player_url = 'https://api.bilibili.com/x/player/playurl' - '''运行主程序''' - def run(self): - while True: - userid = input('请输入目标用户ID(例:243766613) ——> ') - 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) - 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) - 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')) - 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 + 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 = 'https://api.bilibili.com/x/space/acc/info' + self.submit_videos_url = 'https://space.bilibili.com/ajax/member/getSubmitVideos' + self.view_url = 'https://api.bilibili.com/x/web-interface/view' + self.video_player_url = 'https://api.bilibili.com/x/player/playurl' + '''运行主程序''' + def run(self): + while True: + userid = input('请输入目标用户ID(例:243766613) ——> ') + 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) + 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) + 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')) + 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='用户名', type=str, required=True) - parser.add_argument('--password', dest='password', help='密码', type=str, required=True) - args = parser.parse_args() - bili = Bilibili(args.username, args.password) - bili.run() \ No newline at end of file + parser = argparse.ArgumentParser(description='下载B站指定用户的所有视频(仅支持Windows下使用)') + parser.add_argument('--username', dest='username', help='用户名', type=str, required=True) + parser.add_argument('--password', dest='password', help='密码', type=str, required=True) + args = parser.parse_args() + bili = Bilibili(args.username, args.password) + bili.run() \ No newline at end of file