Batch download the learning videos of station B to the local in MP4 format

Batch download the learning videos of station B to the local in MP4 format

1. Background description

Some friends who love to learn may have the habit of caching the learning videos in advance before going out or returning to their hometown for the holiday, but the cached videos can only be Bilibiliviewed in the app, and the screen is a little small, so I prefer to download it to the computer , and then watch it with your favorite player (eg potPlayer).

This blog will share a JS script that uses free parsing websites to achieve batch video downloads.

If there is a bug, it will be updated on gitee: https://gitee.com/he_fu_ren/bilibili-video-download

注:本脚本仅供学习使用,切勿用于商业用途

Second, the effect map

Take the following video with a small number of episodes as an example, you can see that this tutorial has 13 Parts

Please add image description

Screenshot of script running

Please add image description

Please add image description

Download file screenshot

Please add image description

3. Code

The programming language used in this script is JavaScript, which can be run directly in the browser

let inputElement = document.getElementsByTagName('input')[0];
let resolveBtn = document.getElementsByClassName('btn')[0];
let beginTime = 0;
let downloadCount = 0;
let resolveCount = 0;
// 视频的前缀,只需要修改 .../video/av?p= 中的 av 号即可
let prefix = "https://www.bilibili.com/video/BV1q4411y7Zh/?p=";
// 从点击完解析按钮到解析完成的时间间隔,默认2s
let interval = 2000;
// 从第几集开始下载,默认是从第一集开始
let beginPart = 1;
// 要下载的视频的集数
let num = 13;
let retryCandidate = new Array(13);
retryCandidate.fill(1);
let retryTime = (interval + 1000) * num;



function downloadVideo(url,name) {
    
    
   //创建XMLHttpRequest对象
   let httpRequest = new XMLHttpRequest();
   //打开连接,将请求参数拼在url后面
   httpRequest.open('GET', url, true);
   //设置期望的返回值类型
   httpRequest.responseType = "blob";
   //请求成功回调函数
   httpRequest.onload = function (oEvent) {
    
    
       if (httpRequest.status === 200) {
    
    
          let fileName = decodeURI(name+'.mp4');
          let response = httpRequest.response;
          //数据转换为文件下载
          let elink = document.createElement('a');
          elink.download = fileName;
          elink.style.display = 'none';
          let blob = new Blob([response]);
          elink.href = URL.createObjectURL(blob);
          document.body.appendChild(elink);
          elink.click();
          document.body.removeChild(elink);
          console.log('视频' + fileName + '下载完成');
          downloadCount = downloadCount + 1;
          console.log('下载进度' + downloadCount + '/' + num);

       }else {
    
    
          console.log('请求失败,视频url ' + url);
       }
   }

   httpRequest.send();
   
};

function resolve(i) {
    
    
   if (document.getElementsByClassName('caption').length > 0) {
    
    
      // 获取解析后的url
      let url = document.getElementsByClassName('caption')[0].getElementsByTagName('p')[1].getElementsByTagName('a')[0].getAttribute('href');
      // 获取文件名
      let name= document.getElementsByClassName('caption')[0].getElementsByTagName('p')[0].innerText;
      resolveCount = resolveCount + 1;
      retryCandidate[i] = 0;
      downloadVideo(url, name);
   } else {
    
    
      console.log('第' + i + '集视频解析失败,稍后将会重试');
   }
   console.log('解析进度:' + resolveCount + '/' + num);
};

function sendResolvRequest(i) {
    
    
   console.log('当前正在解析第' + i + '集视频');
   // url
   let bilibiliUrl = prefix + i;
   inputElement.value = bilibiliUrl;
   let evt = document.createEvent('HTMLEvents');
   evt.initEvent('input',true,true);
   inputElement.dispatchEvent(evt);
   // 触发按钮点击事件
   resolveBtn.click();
   // 解析结果
   setTimeout(resolve(i),interval);
};

function doRetry() {
    
    
   console.log('开始重试');
   let len = retryCandidate.length;
   beginTime = 0;
   console.log('剩余解析失败的视频数量:',len);
   for(let i = 0; i < len; i++) {
    
    
      if (retryCandidate[i] == 1) {
    
    
         setTimeout(function(){
    
    
            sendResolvRequest(i);
         },beginTime);
         beginTime = beginTime + interval + 1000;
      }
   }
   let retryTime = (interval + 1000) * len ;
   setTimeout(function() {
    
    
      retry();
   },retryTime);
}

function retry() {
    
    
   if (resolveCount < num) {
    
    
      doRetry()
   }
}

for(let i = beginPart; i <= num; i++) {
    
    
   setTimeout(function(){
    
    
      sendResolvRequest(i);
   },beginTime);
   beginTime = beginTime + interval + 1000;
}
setTimeout(function() {
    
    
   retry();
},retryTime);

Fourth, use the tutorial

first step

Open the video analysis URL: https://bilibili.iiilab.com/

second step

Press to F12open the console or 右键web page and then click again 检查, open the console and click `Consoles to switch to the console interface

third step

Copy all the above code into a text editor and modify it according to your own situation

The modifiable part is at the top of the code:

// 视频的前缀,只需要修改 .../video/【av】?p= 中括号内的部分即可,av号在对应B站视频的url中可以看到
let prefix = "https://www.bilibili.com/video/BV1q4411y7Zh/?p=";
// 从点击完解析按钮到解析完成的时间间隔,默认2s(2000ms),网速如果比较慢就改大一些
let interval = 2000;
// 从第几集开始下载,默认是从第一集开始
let beginPart = 1;
// 要下载的视频的集数,配合上面的参数,就是下载1-13集视频
let num = 13;

After the modification, you can paste the modified code into the web page opened in the first step.

illustrate

This script is only for learning use. It is currently the first-generation version, and there may be some small bugs, such as the possibility of missing to download individual videos, etc. It will be repaired when there is time and submitted to git

Guess you like

Origin blog.csdn.net/weixin_44829930/article/details/123762703