前言 MATS在bilibili当UP主(MATSD10S )发布了不少视频,他告诉我第二天要删掉一些早期视频,吓得我想立刻把他的视频都下载下来好好收藏,于是这个程序就出来了
想法 我知道有这么一款命令行式的工具 特别方便,叫做you-get (使用python编写),下载视频相当方便,如果直接使用它,能够省下不少功夫
使用程序调用you-get,只需要一个个自动填入视频ID下载就行了
为保证you-get能使用,请使用pip或其它方法安装you-get 
 
为了迅速完成,我选择了Python3进行程序编写
运行截图 我已经把他的视频都下载下来了,如果你想收藏你喜欢的UP主的视频,这个程序或许对你有些帮助
运行中 
完成任务 
开始介绍 有兴趣的话建议先跳到本文的“相关知识 ”处再返回此处,无兴趣的话可以直接跳到“完整程序 ”复制程序使用
什么!你都不需要?那就随便看看吧,关掉这个页面也行
第一步 确定思路: 
1、you-get只能下载一个页面中的视频,下载一个UP主的所有视频,就一次次调用you-get
2、调用you-get需要提供页面网址(可简化为视频ID),那么就要获取所有视频ID
3、猜想有输入UP主ID 的接口可以调用,直接获取所有视频ID
验证: 
完全可行,相关信息可见本文的“相关知识 ”处
第二步 选择程序语言 
为保证较短时间完成,使用Python3作为编写语言
第三步 开始编写程序 
获取获取所有视频ID
注意页面数需试出来,返回的JSON信息没有提到页面总数(**#遍历所有页面** 处)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 json_headers_setting = {"user-agent"  : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36" } def  get_json_use_id (inf_setup ):  req_s = requests.Session()   json_all_data = req_s.get("https://api.bilibili.com/x/space/arc/search?mid={}" .format (inf_setup), headers=json_headers_setting).text   del  req_s   return  json_all_data dict_json_d = [] for  i in  range (1 , 1000 ):  data_id_all = json.loads(get_json_use_id("{}&pn={}" .format (up_id, i)))   if  data_id_all["data" ]["list" ]["vlist" ] == []:     break    dict_json_d.append(data_id_all) 
 
获取视频清晰度、格式信息 
1 2 3 4 5 6 7 8 9 process = subprocess.Popen("you-get --json "  + url_set, shell=True , stdout=subprocess.PIPE, stderr=subprocess.STDOUT) r_json = str (process.stdout.read().decode('utf-8' )) json_d_inf = json.loads(r_json) down_command = ""  for  i in  json_d_inf["streams" ]:  data_j_get = json_d_inf["streams" ][str (i)] 
 
选择最高清晰度、MP4格式 
1 2 3 4 5 6 7 8 9 10 11 12 process = subprocess.Popen("you-get --json "  + url_set, shell=True , stdout=subprocess.PIPE, stderr=subprocess.STDOUT) r_json = str (process.stdout.read().decode('utf-8' )) json_d_inf = json.loads(r_json) down_command = ""  for  i in  json_d_inf["streams" ]:  data_j_get = json_d_inf["streams" ][str (i)]   down_command = str (i)   if  data_j_get["container" ] == "mp4" :      break  
 
注意判断是否为多P视频,多P视频会有提示信息在开头 或者结尾 出现导致JSON无法被正确加载
变量d_ctl就是为了指示是否不是 多P视频
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 d_ctl = True  if  r_json[0 :1 ] != "{" :  count_a = 0    for  a in  r_json:    if  a == "{"  or  a == "[" :      break     else :      count_a += 1       ppp = "-p"       d_ctl = False    r_json = r_json[count_a:] if  r_json[-3 :-2 ] != "}" :  ppp = "-p"    d_ctl = False    r_json = r_json[:r_json.rindex("}" )+1 ] 
 
第四步 前面信息已经准备完了,直接开始下载
1 2 3 4 if  d_ctl:  os.system("you-get --format={} {}" .format (down_command, url_set) else :  os.system("you-get --playlist {}" .format (url_set)) 
 
所有步骤就到这里了
完整程序 程序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 import  jsonimport  subprocessimport  osimport  requestsfrom  datetime import  datetimeup_id = "102067913"   down_work_dir = "./video"   json_headers_setting = {"user-agent"  : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36" } if  os.path.isdir(down_work_dir) == False :  os.mkdir(down_work_dir) def  down_when_vid_set (url_set ):     process = subprocess.Popen("you-get --json "  + url_set, shell=True , stdout=subprocess.PIPE, stderr=subprocess.STDOUT)   r_json = str (process.stdout.read().decode('utf-8' ))      ppp = ""    d_ctl = True       if  r_json[0 :1 ] != "{" :     count_a = 0      for  a in  r_json:      if  a == "{"  or  a == "[" :        break       else :        count_a += 1         ppp = "-p"         d_ctl = False      r_json = r_json[count_a:]   if  r_json[-3 :-2 ] != "}" :     ppp = "-p"      d_ctl = False      r_json = r_json[:r_json.rindex("}" )+1 ]         json_d_inf = json.loads(r_json)      title_get = json_d_inf["title" ]   down_command = ""       for  i in  json_d_inf["streams" ]:     data_j_get = json_d_inf["streams" ][str (i)]     down_command = str (i)     if  data_j_get["container" ] == "mp4" :       break       now_ttime = datetime.now().strftime('%a,%b%d,%H-%M-%S' )   dir_set = "{}/{}{}" .format (down_work_dir, now_ttime, ppp)   os.mkdir(dir_set)   if  d_ctl:     os.system("you-get --format={} {} -o {}" .format (down_command, url_set, dir_set))   else :     os.system("you-get --playlist {} -o {}" .format (url_set, dir_set)) def  get_json_use_id (inf_setup ):  req_s = requests.Session()   json_all_data = req_s.get("https://api.bilibili.com/x/space/arc/search?mid={}" .format (inf_setup), headers=json_headers_setting).text   del  req_s   return  json_all_data dict_json_d = [] for  i in  range (1 , 1000 ):  data_id_all = json.loads(get_json_use_id("{}&pn={}" .format (up_id, i)))   if  data_id_all["data" ]["list" ]["vlist" ] == []:     break    dict_json_d.append(data_id_all) count_all = 0  count_q = 0  for  i in  dict_json_d:  for  ii in  i["data" ]["list" ]["vlist" ]:     count_all += 1  for  i in  dict_json_d:  for  ii in  i["data" ]["list" ]["vlist" ]:          count_q += 1      if  count_q > 0 :      print("Process at {:.1f}%" .format ((count_q/count_all)*100 ))      try :        print("At " , ii["bvid" ])        down_when_vid_set("https://www.bilibili.com/video/{}" .format (ii["bvid" ]))      except :        print("Error at " , ii["bvid" ])        os.mkdir(ii["bvid" ]) 
 
使用方法 修改此处,改成需要的UP主
1 up_id = "102067913" #设置UP主的ID 
 
然后运行程序
相关知识 一些知识 了解you-get简单使用 简单用法 使用如下命令可以获取一个视频的可下载列表 
 
下载单个视频 按照上图它提示的**you-get –format= [URL]**就可以开始选择需要的清晰度开始下载啦
按JSON返回信息 根据you-get的使用提示,还可以使用
 
来获取可下载列表,这样可以方便程序处理
下载多P视频 考虑到B站存在视频分Part
当遇到多P视频时使用这个命令下载省事很多,需要注意的是,下载的是FLV格式视频
 
设置下载存储文件夹  
如上就是本文所涉及的所有you-get使用方法
在Python3中 requests库的部分用法 发起GET请求 只需要GET就能获取指定JSON,所以这里不提POST用法
1 2 3 4 import  requestsreq_s = requests.Session() json_all_data = req_s.get("https://api.bilibili.com/" ) del  req_s
 
设置请求头(伪造请求头) 为了防止网站认为是脚本进行抓取而拒绝访问,伪造请求头来假装自己是浏览器
设置header
1 json_headers_setting = {"user-agent"  : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36" } 
 
headers=
1 2 3 4 import  requestsreq_s = requests.Session() json_all_data = req_s.get("https://api.bilibili.com/" , headers=json_headers_setting) del  req_s
 
获取回复信息 .text
1 2 3 4 import  requestsjson_all_data = req_s.get("https://api.bilibili.com/" , headers=json_headers_setting).text print(json_all_data) del  req_s
 
安装requests库 如果提示requests无法调用,你可能还没有安装,可以使用pip进行安装
 
目录 操作需要os库
 
目录创建 有时可能会操作失败,最好使用try方法执行此语句
 
目录存在判断 此语句 目录存在就不新建目录 时会使用
 
运行命令行(CMD或shell) 用于调用you-get,当然也可以import you-get而不使用2这个方法 
无输出(但可以将运行结果赋值给字符串)
演示运行ls命令
1 2 3 import  subprocessprocess = subprocess.Popen("ls" , shell=True , stdout=subprocess.PIPE, stderr=subprocess.STDOUT) r_json = process.stdout.read().decode('utf-8' ) 
 
直接运行
1 2 import  osos.system("ls" ) 
 
当前时间获取 使用python3自带的datetime库
1 2 3 from  datetime import  datetimenow_ttime = datetime.now().strftime('%a,%b%d,%H-%M-%S' ) print(now_ttime) 
 
运行上述程序可以获得类似输出
 
JSON的使用 加载JSON 1 2 import  jsonjson.loads() 
 
读取JSON 1 2 3 4 import  jsonj = '{"a" : "123abc"}'  aaa = json.loads(j) print(aaa["a" ]) 
 
一些必须提前获取的东西 获取一个UP主所有的视频ID 根据请求追踪,我找到了这个网址
1 https://api.bilibili.com/x/space/arc/search?mid= 
 
把UP主的ID填上去就能获取一串JSON,不过只记录了第一页的视频ID
想获取所有视频ID就得传入页数了
 
获取ID的示例链接 示例 示例如下,可以获取该UP主第二页的视频
1 https://api.bilibili.com/x/space/arc/search?mid=102067913&pn=2 
 
注意 但是如果超过了UP主发布的视频页数,返回的JSON里的视频ID就会为空 ,所以需要注意
获取允许下载的视频参数 Bilibili上的视频是有清晰度 的,而且还分FLV和MP4 两种格式,所以使用you-get下载前最好先获取清晰度,再按此清晰度进行操作,否则会出错而无法下载
前面提过you-get可以返回json信息方便处理
写在最后 谢谢你能看到这里,希望文章能对你有些帮助
EOF