Easy to download images from BilibiliCV!!
// ==UserScript==
// @name Bilibili CV Downloader
// @namespace https://github.com/hv0905/bilibiliCv_downloader
// @version 1.4
// @description Easy to download images from BilibiliCV!!
// @author EdgeNeko(Github@hv0905)
// @match *://www.bilibili.com/read/cv*
// @grant GM_download
// @grant GM_info
// @grant GM_xmlhttpRequest
// @connect i0.hdslb.com
// ==/UserScript==
//Bilibili CV Downloader
//build with love by EdgeNeko
//Github: @hv0905
//github project: https://github.com/hv0905/bilibiliCv_downloader/
'use strict';
const baseDownload = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTQ1Mzk5NzI5NzM1IiBjbGFzcz0iaWNvbiIgc3R5bGU9IiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjI5MzciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PGRlZnM+PHN0eWxlIHR5cGU9InRleHQvY3NzIj48L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNMTYwIDMyYy0xMiAwLTI0LjggNC44LTMzLjYgMTQuNFMxMTIgNjggMTEyIDgwdjg2NGMwIDEyIDQuOCAyNC44IDE0LjQgMzMuNiA5LjYgOS42IDIxLjYgMTQuNCAzMy42IDE0LjRoNzA0YzEyIDAgMjQuOC00LjggMzMuNi0xNC40IDkuNi05LjYgMTQuNC0yMS42IDE0LjQtMzMuNlYzMDRMNjQwIDMySDE2MHoiIGZpbGw9IiM1QUNDOUIiIHAtaWQ9IjI5MzgiPjwvcGF0aD48cGF0aCBkPSJNOTEyIDMwNEg2ODhjLTEyIDAtMjQuOC00LjgtMzMuNi0xNC40LTkuNi04LjgtMTQuNC0yMS42LTE0LjQtMzMuNlYzMmwyNzIgMjcyeiIgZmlsbD0iI0JERUJENyIgcC1pZD0iMjkzOSI+PC9wYXRoPjxwYXRoIGQ9Ik01MDAuOCA2ODQuOGMzLjIgMi40IDYuNCA0LjggMTEuMiA0LjggNCAwIDgtMS42IDExLjItNC44bDE0Mi40LTEzNmMyLjQtMi40IDMuMi01LjYgMS42LTguOC0xLjYtMy4yLTQtNC44LTcuMi00LjhINTc2di0xMzZjMC00LTEuNi04LTQuOC0xMS4yLTMuMi0zLjItNy4yLTQuOC0xMS4yLTQuOEg0NjRjLTQgMC04IDEuNi0xMS4yIDQuOC0zLjIgMy4yLTQuOCA3LjItNC44IDExLjJ2MTM2SDM2NGMtMy4yIDAtNi40IDEuNi03LjIgNC44LTEuNiAzLjIgMCA2LjQgMS42IDguOGwxNDIuNCAxMzZ6TTcxMiA3NTEuMkgzMTJjLTguOCAwLTE2IDcuMi0xNiAxNnM3LjIgMTYgMTYgMTZoNDAwYzguOCAwIDE2LTcuMiAxNi0xNnMtNy4yLTE2LTE2LTE2eiIgZmlsbD0iI0ZGRkZGRiIgcC1pZD0iMjk0MCI+PC9wYXRoPjwvc3ZnPg==';
var lastDownloadTime = 0;
var missionCount = 0;
var completedMissionCount = 0;
var replaceTarget;
var downloaded = false;
function ondownload() {
'use strict';
setNotifyText('开始下载');
let elements = document.getElementsByClassName('img-box');
for (let i = 0; i < elements.length; i++) {
let img = elements[i].querySelector('img').dataset.src;
if (!img) {
continue;
}
let txt = "";
if (elements[i].querySelector('.caption')) {
//caption
txt = elements[i].querySelector('.caption').innerHTML.trim();
}
let imgOriginal = img.split('@')[0];
let fileName;
if(txt.length == 0){
let urlSplit = imgOriginal.split('/');
fileName = urlSplit[urlSplit.length - 1];
}else{
let extSplits = imgOriginal.split('.');
fileName = txt.replace('\\','_').replace('/','_').replace('?','_').replace(':','_').replace('*','_').replace('|','_').replace('<','_').replace('>','_').replace('"','_') + '.' + extSplits[extSplits.length - 1];
}
console.log(`[${i}]准备下载:${imgOriginal} 文件名:${fileName}`);
missionCount++;
//瞬间完成
downloadFileBlob('https:' + imgOriginal, fileName, i);
}
}
function downloadFileBlob(url, fileName, i) {
'use strict';
GM_xmlhttpRequest({
method: 'GET',
url: url,
responseType: 'blob',
timeout: 180000,
onload: function (xhr) {
let blobURL = window.URL.createObjectURL(xhr.response); // 返回的blob对象是整个response,而非responseText
saveBlob(blobURL, fileName);
},
onprogress: function (xhr) {
let loaded = parseInt(xhr.loaded / 1000);
let total = parseInt(xhr.total / 1000);
console.log(`[${i}]正在下载:${fileName} 进度:${(loaded / total)}`);
},
});
}
function saveBlob(blob, fileName) {
'use strict';
if (new Date().getTime() - lastDownloadTime < 200) {
setTimeout(() => {
saveBlob(blob, fileName);
}, 200 - (new Date().getTime() - lastDownloadTime));
return;
}
lastDownloadTime = new Date().getTime();
console.log("正在保存:" + fileName);
let a = $('<a>')
.attr('href', blob)
.attr('download', fileName)
.appendTo('body');
a[0].click();
a.remove();
window.URL.revokeObjectURL(blob);
completedMissionCount++;
checkIfCompleted();
}
function checkIfCompleted() {
'use strict';
if (missionCount <= completedMissionCount) {
alert('所有下载操作已完成!\n你可以关闭网页了');
setNotifyText('下载完成!');
} else {
setNotifyText(`下载进度:${completedMissionCount}/${missionCount}`);
}
}
function setNotifyText(text) {
'use strict';
replaceTarget.children[1].innerText = text;
}
(function () {
'use strict';
onload = function () {
replaceTarget = this.document.getElementsByClassName('help')[0];
let replaceA = replaceTarget.parentElement;
replaceA.href = 'javascript:void(0)';
replaceA.target = '';
replaceA.onclick = function () {
if (downloaded) return;
if (confirm('确认下载全部图片?\n注意:在弹出下载成功提示前请不要关闭窗口,否则无法保证所有图片均下载完成\n要查看进度,请点击F12并转到Console')) {
ondownload();
downloaded = true;
}
}
replaceTarget.children[0].style.backgroundImage = 'url(' + baseDownload + ')';
replaceTarget.children[1].innerText = '下载所有图片';
replaceTarget.children[2].innerText = 'by EdgeNeko'
};
})();