|
| 1 | +from time import sleep |
| 2 | +import requests, urllib.request, re |
| 3 | +import os, sys,json |
| 4 | + |
| 5 | +headers = { |
| 6 | + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36', |
| 7 | + 'Cookie': 'SESSDATA=182cd036%2C1636985829%2C3b393%2A51', |
| 8 | + 'Host': 'api.bilibili.com' |
| 9 | + } |
| 10 | + |
| 11 | + |
| 12 | +Str = 'fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF' # 准备的一串指定字符串 |
| 13 | +Dict = {} |
| 14 | + |
| 15 | +# 将字符串的每一个字符放入字典一一对应 , 如 f对应0 Z对应1 一次类推。 |
| 16 | +for i in range(58): |
| 17 | + Dict[Str[i]] = i |
| 18 | + |
| 19 | +s = [11, 10, 3, 8, 4, 6, 2, 9, 5, 7] # 必要的解密列表 |
| 20 | +xor = 177451812 |
| 21 | +add = 100618342136696320 # 这串数字最后要被减去或加上 |
| 22 | + |
| 23 | +def algorithm_enc(av): |
| 24 | + ret = av |
| 25 | + av = int(av) |
| 26 | + av = (av ^ xor) + add |
| 27 | + # 将BV号的格式(BV + 10个字符) 转化成列表方便后面的操作 |
| 28 | + r = list('BV ') |
| 29 | + for i in range(10): |
| 30 | + r[s[i]] = Str[av // 58 ** i % 58] |
| 31 | + return ''.join(r) |
| 32 | + |
| 33 | +def find_bid(p): |
| 34 | + bids = [] |
| 35 | + r = requests.get( |
| 36 | + 'https://api.bilibili.com/x/web-interface/newlist?&rid=20&type=0&pn={}&ps=50&jsonp=jsonp'.format(p)) |
| 37 | + |
| 38 | + data = json.loads(r.text) |
| 39 | + archives = data['data']['archives'] |
| 40 | + |
| 41 | + for item in archives: |
| 42 | + aid = item['aid'] |
| 43 | + # r = requests.get('http://api.bilibili.com/x/web-interface/archive/stat?aid=' + str(aid), headers=headers) |
| 44 | + # bid = json.loads(r.text)['data']['bvid'] |
| 45 | + bid = algorithm_enc(aid) |
| 46 | + bids.append(bid) |
| 47 | + |
| 48 | + return bids |
| 49 | + |
| 50 | + |
| 51 | +def get_cid(bid): |
| 52 | + url = 'https://api.bilibili.com/x/player/pagelist?bvid=' + bid |
| 53 | + |
| 54 | + |
| 55 | + html = requests.get(url, headers=headers).json() |
| 56 | + |
| 57 | + infos = [] |
| 58 | + |
| 59 | + data = html['data'] |
| 60 | + cid_list = data |
| 61 | + for item in cid_list: |
| 62 | + cid = item['cid'] |
| 63 | + title = item['part'] |
| 64 | + infos.append({'bid': bid, 'cid': cid, 'title': title}) |
| 65 | + return infos |
| 66 | + |
| 67 | + |
| 68 | +# 访问API地址 |
| 69 | +def get_video_list(aid, cid, quality): |
| 70 | + url_api = 'https://api.bilibili.com/x/player/playurl?cid={}&bvid={}&qn={}'.format(cid, aid, quality) |
| 71 | + headers = { |
| 72 | + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36', |
| 73 | + 'Cookie': 'SESSDATA=182cd036%2C1636985829%2C3b393%2A51', |
| 74 | + 'Host': 'api.bilibili.com' |
| 75 | + } |
| 76 | + html = requests.get(url_api, headers=headers).json() |
| 77 | + video_list = [] |
| 78 | + |
| 79 | + for i in html['data']['durl']: |
| 80 | + video_list.append(i['url']) |
| 81 | + return video_list |
| 82 | + |
| 83 | + |
| 84 | +# 下载视频 |
| 85 | + |
| 86 | +def schedule_cmd(blocknum, blocksize, totalsize): |
| 87 | + percent = 100.0 * blocknum * blocksize/ totalsize |
| 88 | + s = ('#' * round(percent)).ljust(100, '-') |
| 89 | + sys.stdout.write('%.2f%%' % percent + '[' + s + ']' + '\r') |
| 90 | + sys.stdout.flush() |
| 91 | + |
| 92 | +# 下载视频 |
| 93 | +def download(video_list, title, bid): |
| 94 | + for i in video_list: |
| 95 | + opener = urllib.request.build_opener() |
| 96 | + # 请求头 |
| 97 | + opener.addheaders = [ |
| 98 | + ('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36'), |
| 99 | + ('Accept', '*/*'), |
| 100 | + ('Accept-Language', 'en-US,en;q=0.5'), |
| 101 | + ('Accept-Encoding', 'gzip, deflate, br'), |
| 102 | + ('Range', 'bytes=0-'), |
| 103 | + ('Referer', 'https://www.bilibili.com/video/'+bid), |
| 104 | + ('Origin', 'https://www.bilibili.com'), |
| 105 | + ('Connection', 'keep-alive'), |
| 106 | + |
| 107 | + ] |
| 108 | + |
| 109 | + filename=os.path.join('D:\\video', r'{}_{}.mp4'.format(bid,title)) |
| 110 | + |
| 111 | + try: |
| 112 | + urllib.request.install_opener(opener) |
| 113 | + urllib.request.urlretrieve(url=i, filename=filename, reporthook=schedule_cmd) |
| 114 | + except: |
| 115 | + print(bid + "下载异常,文件:" + filename) |
| 116 | + |
| 117 | +if __name__ == '__main__': |
| 118 | + # algorithm_enc(545821176) |
| 119 | + bids = find_bid(1) |
| 120 | + print(len(bids)) |
| 121 | + for bid in bids: |
| 122 | + sleep(10) |
| 123 | + cid_list = get_cid(bid) |
| 124 | + |
| 125 | + for item in cid_list: |
| 126 | + cid = item['cid'] |
| 127 | + title = item['title'] |
| 128 | + title = re.sub(r'[\/\\:*?"<>|]', '', title) # 替换为空的 |
| 129 | + bid = item['bid'] |
| 130 | + video_list = get_video_list(bid, cid, 80) |
| 131 | + |
| 132 | + download(video_list, title, bid) |
0 commit comments