def get_user_info(self): if self.uid is None: raise BaseException('缺少必要的参数') f.print_1('正在获取用户信息...', end='') param = {'mid': str(self.uid), 'jsonp': 'jsonp'} http_result = requests.get(url=v.URL_UP_INFO, params=param, headers=f.new_http_header(v.URL_UP_INFO)) if http_result.status_code == 200: f.print_g('OK {}'.format(http_result.status_code)) else: f.print_r('RE {}'.format(http_result.status_code)) json_data = json.loads(http_result.text) if json_data['code'] != 0: raise BaseException('获取数据的过程发生错误') # 修改对象信息 self.uid = json_data['data']['mid'] self.name = json_data['data']['name'] self.birthday = json_data['data']['birthday'] self.coin = json_data['data']['coins'] self.face = json_data['data']['face'] self.time = json_data['data']['jointime'] self.level = json_data['data']['level'] self.sex = json_data['data']['sex'] self.sign = json_data['data']['sign'] return copy.deepcopy(vars(self))
def get_channel_video_info(self): # 获取UP所有频道的所有视频 if self.uid is None: raise BaseException('缺少必要的参数') if self.name is None: self.get_user_info() f.print_1('正在获取频道列表...', end='') param = {'mid': str(self.uid), 'guest': False, 'jsonp': 'jsonp'} http_result = requests.get(v.URL_UP_CHANNELS, params=param, headers=f.new_http_header( v.URL_UP_CHANNELS)) if http_result.status_code == 200: f.print_g('OK {}'.format(http_result.status_code)) else: f.print_r('RE {}'.format(http_result.status_code)) json_data = json.loads(http_result.text) if json_data['code'] != 0: raise BaseException('获取数据的过程发生错误') for channel in json_data['data']['list']: ch = Channel(self.uid, channel['cid']) ch.set_cookie(self.cookie) self.channel_list.append(ch) return copy.deepcopy(self.channel_list)
def get_album_data(self, base_path='', name_path=False, max_length=None): if len(self.video_list) == 0: try: self.get_album_info() except LookupError as e: f.print_r('{},已跳过'.format(e)) return base_path = os.path.abspath(base_path) # 获取绝对路径地址 if name_path: # 检查路径名中的特殊字符 temp_name = re.sub(r"[\/\\\:\*\?\"\<\>\|\s'‘’]", '_', self.name) if len(temp_name) == 0: temp_name = self.aid cache_path = base_path + '/{}'.format(temp_name) else: cache_path = base_path + '/{}'.format(self.aid) if not os.path.exists(cache_path): os.makedirs(cache_path) f.print_1('正在获取视频封面--', end='') f.print_b('av:{}'.format(self.aid)) http_result = requests.get(self.cover) with open(cache_path + '/cover.jpg', 'wb') as file: file.write(http_result.content) f.print_g('[OK]', end='') f.print_1('视频封面已保存') for video in self.video_list: video.get_video_data(cache_path, name_path, max_length) with open(cache_path + '/info.json', 'w', encoding='utf8') as file: file.write(str(json.dumps(self.get_dict_info())))
def get_all_video_data(self, base_path='', name_path=False, max_length=None, exclude_list=None): if len(self.album_list) == 0: self.get_all_video_info() if name_path: # 检查路径名中的特殊字符 temp_name = re.sub(r"[\/\\\:\*\?\"\<\>\|\s'‘’]", '_', self.name) if len(temp_name) == 0: temp_name = self.uid cache_path = base_path + '/{}'.format(temp_name) else: cache_path = base_path + '/{}'.format(self.uid) if not os.path.exists(cache_path): os.makedirs(cache_path) f.print_1('正在获取用户头像--', end='') f.print_b('user:{}'.format(self.name)) http_result = requests.get(self.face) with open(cache_path + '/face.jpg', 'wb') as file: file.write(http_result.content) f.print_g('[OK]', end='') f.print_1('用户头像已保存') for album in self.album_list: if exclude_list is not None and album.aid in exclude_list: continue album.get_album_data(cache_path, name_path, max_length) with open(cache_path + '/info.json', 'w', encoding='utf8') as file: file.write(str(json.dumps(self.get_dict_info())))
def get_video_data(self, base_path='', name_path=False, max_length=None): if self.video is None and self.audio is None: self.get_video_info() if max_length is not None and max_length < self.length: f.print_y('视频:{},超出限定长度取消下载') return base_path = os.path.abspath(base_path) # 获取绝对路径地址 if name_path: # 检查路径名中的特殊字符 temp_name = re.sub(r"[\/\\\:\*\?\"\<\>\|\s'‘’]", '_', self.name) temp_name = re.sub(r'[‘’]', '_', temp_name) if len(temp_name) == 0: temp_name = self.cid cache_path = base_path + '/{}'.format(temp_name) else: cache_path = base_path + '/{}'.format(self.cid) if not os.path.exists(cache_path): os.makedirs(cache_path) # 使用两个进程分别下载视频和音频 f.print_1('正在下载视频和配套音--', end='') f.print_b('av:{},cv:{}'.format(self.aid, self.cid)) if self.audio is not None and self.video is not None: self.aria2c_download(cache_path, '{}_{}.aac'.format(self.cid, self.quality_des), self.audio) self.aria2c_download(cache_path, '{}_{}.flv'.format(self.cid, self.quality_des), self.video) if self.video is not None and self.audio is None: self.aria2c_download(cache_path, '{}_{}.mp4'.format(self.cid, self.quality_des), self.video) else: f.print_y('无需独立下载音频') f.print_cyan('==============================================================') with open(cache_path + '/info.json', 'w', encoding='utf8') as file: file.write(str(json.dumps(self.get_dict_info())))
def get_channel_video_data(self, base_path='', name_path=False, max_length=None): # 获取UP主的所有视频的数据 if len(self.channel_list) == 0: self.get_channel_video_info() base_path = os.path.abspath(base_path) # 获取绝对路径地址 if name_path: # 检查路径名中的特殊字符 temp_name = re.sub(r"[\/\\\:\*\?\"\<\>\|\s'‘’]", '_', self.name) if len(temp_name) == 0: temp_name = self.uid cache_path = base_path + '/{}'.format(temp_name) else: cache_path = base_path + '/{}'.format(self.uid) if not os.path.exists(cache_path): os.makedirs(cache_path) f.print_1('正在获取用户头像--', end='') f.print_b('user:{}'.format(self.name)) http_result = requests.get(self.face) with open(cache_path + '/face.jpg', 'wb') as file: file.write(http_result.content) f.print_g('[OK]', end='') f.print_1('用户头像已保存') for channel in self.channel_list: channel.get_channel_data(cache_path, name_path, max_length) with open(cache_path + '/info.json', 'w', encoding='utf8') as file: file.write(str(json.dumps(self.get_dict_info())))
def aria2c_download(self, cache_path, file_name, download_url): referer = 'https://www.bilibili.com/video/av' + str(self.aid) shell = 'aria2c -c -s 16 -d "{}" -o "{}" --referer="{}" "{}"' shell = shell.format(cache_path, file_name, referer, download_url) process = subprocess.Popen(shell, shell=True) process.wait() file_path = '{}/{}'.format(cache_path, file_name) if os.path.exists(file_path): f.print_g('[OK]', end='') f.print_1('文件{}下载成功--'.format(file_name), end='') f.print_b('av:{},cv:{}'.format(self.aid, self.cid)) else: f.print_r('[ERR]', end='') f.print_1('文件{}下载失败--'.format(file_name), end='') f.print_b('av:{},cv:{}'.format(self.aid, self.cid)) f.print_r(shell.format(file_path, referer, download_url)) raise BaseException('av:{},cv:{},下载失败'.format(self.aid, self.cid))
def get_album_info(self, proxies=None): if self.aid is None: raise BaseException('缺少必要的参数') f.print_1('正在获取视频信息...', end='') param = {'aid': str(self.aid)} http_result = requests.get(v.URL_UP_ALBUM, params=param, proxies=proxies, headers=f.new_http_header(v.URL_UP_ALBUM)) if http_result.status_code == 200: f.print_g('OK {}'.format(http_result.status_code)) else: f.print_r('RE {}'.format(http_result.status_code)) json_data = json.loads(http_result.text) if json_data['code'] == -404 or json_data['code'] == -403: raise LookupError('稿件av{}异常或被锁定,无法下载'.format(self.aid)) elif json_data['code'] != 0: raise BaseException('获取数据的过程发生错误:av={},code={}'.format( self.aid, json_data['code'])) # 修改对象信息 self.aid = json_data['data']['aid'] self.time = json_data['data']['ctime'] self.desc = json_data['data']['desc'] self.name = json_data['data']['title'] self.zone = json_data['data']['tname'] self.num = json_data['data']['videos'] self.cover = json_data['data']['pic'] self.like = json_data['data']['stat']['like'] self.coin = json_data['data']['stat']['coin'] self.favorite = json_data['data']['stat']['favorite'] self.share = json_data['data']['stat']['share'] self.view = json_data['data']['stat']['view'] self.danmu = json_data['data']['stat']['danmaku'] self.video_list = list() for page in json_data['data']['pages']: cv = Video(self.aid, page['cid'], page['page'], page['part']) cv.set_cookie(self.cookie) self.video_list.append(cv) return copy.deepcopy(vars(self))
def get_video_info(self, qn=116): if self.aid is None or self.cid is None: raise BaseException('缺少必要的参数') f.print_1('正在获取分P信息...', end='') param = { 'avid': str(self.aid), 'cid': str(self.cid), 'qn': qn, # 默认使用最高画质下载 'otype': 'json', 'fnver': 0, 'fnval': 16 } http_result = requests.get(v.URL_UP_VIDEO, params=param, cookies=self.cookie, headers=f.new_http_header(v.URL_UP_INFO)) if http_result.status_code == 200: f.print_g('OK {}'.format(http_result.status_code)) else: f.print_r('RE {}'.format(http_result.status_code)) json_data = json.loads(http_result.text) if json_data['code'] != 0: raise BaseException('获取数据的过程发生错误') # 自动识别不同的数据来源 if 'dash' in json_data['data']: self.quality = json_data['data']['quality'] self.length = json_data['data']['timelength'] self.video = json_data['data']['dash']['video'][-1]['baseUrl'] self.audio = json_data['data']['dash']['audio'][0]['baseUrl'] elif 'durl' in json_data['data']: self.quality = json_data['data']['quality'] self.length = json_data['data']['timelength'] self.video = json_data['data']['durl'][-1]['url'] for index, val in enumerate(json_data['data']['accept_quality']): if val == self.quality: self.quality_des = json_data['data']['accept_description'][ index] break return self
def get_all_video_info(self): # 获取UP主的所有视频的列表信息 if self.uid is None: raise BaseException('缺少必要的参数') if self.name is None: self.get_user_info() f.print_1('正在获取视频列表...', end='') param = { 'mid': str(self.uid), 'pagesize': 30, 'tid': 0, 'page': 1, 'order': 'pubdate' } while True: http_result = requests.get(v.URL_UP_ALL_VIDEO, params=param, headers=f.new_http_header( v.URL_UP_ALL_VIDEO)) if http_result.status_code == 200: f.print_g('OK {}'.format(http_result.status_code)) else: f.print_r('RE {}'.format(http_result.status_code)) json_data = json.loads(http_result.text) if json_data['status'] is not True: raise BaseException('获取数据的过程发生错误') for video in json_data['data']['vlist']: av = Album(video['aid']) av.set_cookie(self.cookie) self.album_list.append(av) # 循环翻页获取并自动退出循环 if len(self.album_list) >= int(json_data['data']['count']): break else: param['page'] += 1 return copy.deepcopy(self.album_list)
def get_channel_info(self): if self.uid is None or self.cid is None: raise BaseException('缺少必要的参数') param = { 'mid': str(self.uid), 'cid': str(self.cid), 'pn': 1, # 当前页码下标 'ps': 30, # 每页视频数量 'order': 0 # 默认排序 } while True: f.print_1('正在获取视频列表-{}...'.format(param['pn']), end='') http_result = requests.get(v.URL_UP_CHANNEL, params=param, headers=f.new_http_header( v.URL_UP_CHANNEL)) if http_result.status_code == 200: f.print_g('OK {}'.format(http_result.status_code)) else: f.print_r('RE {}'.format(http_result.status_code)) json_data = json.loads(http_result.text) if json_data['code'] != 0: raise BaseException('获取数据的过程发生错误') self.name = json_data['data']['list']['name'] self.cover = json_data['data']['list']['cover'] self.count = str(json_data['data']['list']['count']) for album in json_data['data']['list']['archives']: av = Album(album['aid']) av.set_cookie(self.cookie) self.album_list.append(av) # 循环翻页获取并自动退出循环 if len(self.album_list) >= int(json_data['data']['page']['count']): break else: param['pn'] += 1 return copy.deepcopy(vars(self))