// ==UserScript==
// @name 下载当前页面指定数据 (img, video, audio, ...)
// @namespace http://tampermonkey.net/
// @version 1.0.0
// @description 调用 downloadDataInOrder(obtainDataNodes(document.querySelectorAll('数据节点'), 'file')) 方法,并传入数据节点,根据传入的数据节点,下载网页上的数据并保存到本地
// @author slowFever
// @match *://*/*
// @match *
// @connect *
// @grant unsafeWindow
// @grant GM_xmlhttpRequest
// @run-at document-idle
// @downloadURL none
// ==/UserScript==
(function() {
'use strict';
/**
* @name 获取数据节点的函数
* @param nodes 传入单个节点,或多个节点(img, video, audio, ...)
* @returns Array[]
*/
function obtainDataNodes(nodes) {
let nodeDataList = [];
nodes.forEach(node => {
const src = node.getAttribute('src');
if (src && !nodeDataList.includes(src)) {
nodeDataList.push(src);
}
});
console.log(`获取到${nodeDataList.length}条数据`)
return nodeDataList;
}
/**
* @name 下载数据的函数
* @param url 下载地址
* @param name 文件名
*/
function downloadFile(url, filename) {
GM_xmlhttpRequest({
method: "GET",
url: url,
responseType: "blob", // 指定响应类型为 blob
onload: function(response) {
if (response.status === 200) {
const blob = new Blob([response.response]); // 创建 Blob 对象
const link = document.createElement('a'); // 创建 标签
link.href = URL.createObjectURL(blob); // 创建 URL 对象
link.download = filename; // 设置下载的文件名
document.body.appendChild(link); // 添加到文档中
link.click(); // 模拟点击下载
document.body.removeChild(link); // 下载完成后移除 标签
console.log(`成功下载数据:${filename}`);
} else {
console.error('下载失败,状态码:', response.status);
}
},
onerror: function(error) {
console.error('下载出错:', error);
}
});
}
/**
* @name 按顺序下载数据的函数
* @param nodesData 数据节点
* @param prefix 文件名前缀
*/
function downloadDataInOrder(nodesData, prefix = 'file') {
nodesData.forEach((url, index) => {
const fileName = `${prefix}-${index + 1}.${url.split('.').pop().split('?')[0]}`;
downloadFile(url, fileName);
});
}
// 将函数暴露到全局,以便在控制台调用
unsafeWindow.downloadDataInOrder = downloadDataInOrder;
unsafeWindow.obtainDataNodes = obtainDataNodes;
// 提示用户可以通过控制台调用函数
(async () => {
console.log("下载指定数据脚本加载完成,当前版本:", GM_info.script.version);
await new Promise(resolve => setTimeout(resolve, 1000)); // 延时1秒
console.log("%c使用脚本方法:↓ ↓ ↓", "color:#ec2c64");
await new Promise(resolve => setTimeout(resolve, 1000)); // 再延时1秒
console.log("%cdownloadDataInOrder(obtainDataNodes(document.querySelectorAll('数据节点'), 'file'))", "color:#0f59a4; background:#eef7f2; font-size:1.5rem; padding:0.15rem 0.35rem; margin: 1rem auto; font-family: Rockwell; border: 2px solid #0f59a4; border-radius: 4px;font-weight: bold; text-shadow: 1px 1px 1px #0f59a4;");
})();
})();