Guest User

恢复 Bilibili 收藏夹中失效视频

a guest
Jun 12th, 2019
276
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.90 KB | None | 0 0
  1. '''
  2. 需要 Python 3.6 + requests
  3. '''
  4. import requests
  5. from math import ceil
  6. from urllib import parse
  7. import time
  8.  
  9.  
  10. class favlist():
  11.     apiUrl = 'https://api.bilibili.com/medialist/gateway/base/spaceDetail?media_id={fid}&pn={pn}&ps=20'
  12.  
  13.     def __init__(self, url: str):
  14.         '''
  15.        初始化类,对 URL 进行解析,并从 API 中获得收藏夹视频数目
  16.  
  17.        :param url: 收藏夹 URL
  18.        Usage::
  19.            favlist('https://space.bilibili.com/3992364/favlist?fid=45027464')
  20.        '''
  21.         params = self.parse_url(url)
  22.         self.fid = params['fid'][0]
  23.         favList = self.get_content(1)
  24.         self.mediaCount = favList['data']['info']['media_count']
  25.  
  26.     def parse_url(self, inUrl: str):
  27.         '''
  28.        解析 URL,返回参数列表
  29.  
  30.        :param inUrl: 被解析 URL
  31.        :rtype: dict
  32.        '''
  33.         paramStr = parse.urlsplit(inUrl)
  34.         params = parse.parse_qs(paramStr[3])
  35.         return params
  36.  
  37.     def get_content(self, pn: int):
  38.         '''
  39.        通过 API 获得收藏夹内容
  40.  
  41.        :param pn: 收藏夹页数
  42.        :rtype: dict
  43.        '''
  44.         currUrl = self.apiUrl.format(fid=self.fid, pn=pn)
  45.         try:
  46.             apiResp = requests.get(currUrl)
  47.         except requests.HTTPError as e:
  48.             print(f'get_content() error, HTTPError {e}')
  49.             return {}
  50.         except requests.ConnectionError as e:
  51.             print(f'get_content() error, ConnectionError {e}')
  52.             return {}
  53.         else:
  54.             favListJson = apiResp.json()
  55.             return favListJson
  56.  
  57.     def get_failure_media(self):
  58.         '''
  59.        根据标题筛选失效视频
  60.  
  61.        :return: 失效视频列表
  62.        :rtype: list
  63.        '''
  64.         failMedia = []
  65.         currPage = 1
  66.         totalPage = ceil(self.mediaCount/20)
  67.         print('Failure media:')
  68.         while currPage <= totalPage:
  69.             favList = self.get_content(currPage)
  70.             print(f'Page {currPage}:')
  71.             # B站程序员蜜汁英语水平,这个`medias`是怎么回事
  72.             for i in favList['data']['medias']:
  73.                 if i['title'] == '已失效视频':
  74.                     print(f'av{i["id"]}')
  75.                     failMedia.append(i)
  76.             currPage += 1
  77.         return failMedia
  78.  
  79.  
  80. def get_biliplus_data(aid: int):
  81.     plusUrl = f'https://hd.biliplus.com/api/aidinfo?aid={aid}'
  82.     try:
  83.         plusResp = requests.get(plusUrl, timeout=18)
  84.         plusJson = plusResp.json()
  85.         if plusJson['code'] != 0:
  86.             # biliPlus 文档有毒吧,code 的意义只能实验出来...
  87.             raise requests.HTTPError(f'status code {plusJson["code"]}')
  88.     except requests.HTTPError as e:
  89.         print(f'get_biliplus_data(), HTTPError {e}')
  90.         return {}
  91.     except requests.ConnectionError as e:
  92.         print(f'get_biliplus_data(), ConnectionError {e}')
  93.         return {}
  94.     else:
  95.         mediaData = plusJson["data"][str(aid)]
  96.         print(
  97.             f'title: {mediaData["title"]}, author: {mediaData["author"]}, av{aid}')
  98.         return mediaData
  99.  
  100.  
  101. def save_to_file(inStr: str, fileName: str):
  102.     try:
  103.         fp = open(fileName, 'a')
  104.     except IOError as identifier:
  105.         fp = open(fileName, 'w')
  106.     finally:
  107.         fp.write(inStr)
  108.         fp.close()
  109.  
  110.  
  111. if __name__ == "__main__":
  112.     hint = '输入收藏夹URL\n例子: https://space.bilibili.com/3992364/favlist?fid=45027464\n> '
  113.     url = input(hint)
  114.     f = favlist(url)
  115.     fail = f.get_failure_media()
  116.     print('Failure videos detail:')
  117.     for i in fail:
  118.         save_to_file(f'av{i["id"]}\n', 'avNum.txt')
  119.         plus = get_biliplus_data(i['id'])
  120.         if len(plus) != 0:
  121.             save_to_file(f'{plus["title"]},{plus["author"]},av{i["id"]}\n', 'result.csv')
  122.         # biliPlus 的土豆服务器一分钟只能请求 5 次
  123.         # 而且还经常爆炸
  124.         time.sleep(20)
Advertisement
Add Comment
Please, Sign In to add comment