Wiley 补充材料批量打包下载
在 Wiley 文章页面,脚本会自动在右上角生成控制面板,无需额外操作。
复制以下代码到脚本管理器,保存即用。
// ==UserScript==
// @name Wiley 补充材料批量打包下载(右侧黑白灰+file命名)
// @namespace http://tampermonkey.net/
// @version 1.4
// @description 修复面板不显示问题,右侧黑白灰样式,提取file=文件名,文件直放ZIP根目录
// @author 定制脚本
// @match https://*.onlinelibrary.wiley.com/*
// @grant none
// @require https://cdn.jsdelivr.net/npm/jszip@3.10.1/dist/jszip.min.js
// @require https://cdn.jsdelivr.net/npm/file-saver@2.0.5/dist/FileSaver.min.js
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 解析 file= 参数获取文件名
const getFileName = (url) => {
let name = '';
const fileMatch = url.match(/file=([^&]+)/);
if (fileMatch && fileMatch[1]) {
name = decodeURIComponent(fileMatch[1]);
} else {
const fnMatch = url.match(/filename=([^&]+)/);
name = fnMatch ? decodeURIComponent(fnMatch[1]) : '';
}
return name.replace(/[\\/:*?"<>|]/g, '_') || 'unknown_file';
};
// 创建控制面板
function createPanel(links) {
if (document.getElementById('wiley_supplement_panel')) return;
const panel = document.createElement('div');
panel.id = 'wiley_supplement_panel';
panel.style.cssText = `
position: fixed; top: 20px; right: 20px; z-index: 999999;
background: #f8f8f8; border: 1px solid #ccc; border-radius: 6px;
padding: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.15);
font-size: 14px; width: 320px; color: #333;
`;
const title = document.createElement('div');
title.textContent = `📦 补充材料打包下载 (${links.length} 个文件)`;
title.style.fontWeight = 'bold';
title.style.marginBottom = '8px';
title.style.color = '#222';
panel.appendChild(title);
const selectBtn = document.createElement('button');
selectBtn.textContent = '全选 / 反选';
selectBtn.style.margin = '0 5px 8px 0';
selectBtn.style.padding = '4px 8px';
selectBtn.style.border = '1px solid #999';
selectBtn.style.background = '#eee';
selectBtn.style.color = '#333';
selectBtn.style.borderRadius = '3px';
selectBtn.style.cursor = 'pointer';
panel.appendChild(selectBtn);
const downloadBtn = document.createElement('button');
downloadBtn.textContent = '✅ 打包下载选中文件';
downloadBtn.style.background = '#666';
downloadBtn.style.color = '#fff';
downloadBtn.style.border = '1px solid #555';
downloadBtn.style.borderRadius = '3px';
downloadBtn.style.padding = '4px 12px';
downloadBtn.style.cursor = 'pointer';
panel.appendChild(downloadBtn);
const fileList = document.createElement('div');
fileList.style.maxHeight = '200px';
fileList.style.overflowY = 'auto';
fileList.style.marginTop = '8px';
fileList.style.borderTop = '1px solid #ddd';
fileList.style.paddingTop = '8px';
panel.appendChild(fileList);
document.body.appendChild(panel);
const checkboxes = [];
links.forEach((link) => {
const fileName = getFileName(link.href);
const item = document.createElement('div');
item.style.margin = '3px 0';
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.checked = true;
checkbox.value = link.href;
const label = document.createElement('span');
label.textContent = fileName;
label.style.marginLeft = '5px';
item.appendChild(checkbox);
item.appendChild(label);
fileList.appendChild(item);
checkboxes.push(checkbox);
});
// 全选反选
let isAllChecked = true;
selectBtn.onclick = () => {
isAllChecked = !isAllChecked;
checkboxes.forEach(cb => cb.checked = isAllChecked);
};
// 打包下载
downloadBtn.onclick = async () => {
const selected = checkboxes.filter(cb => cb.checked).map(cb => cb.value);
if (selected.length === 0) {
alert('请至少选择一个文件');
return;
}
downloadBtn.textContent = '⏳ 正在打包,请稍等...';
downloadBtn.disabled = true;
const zip = new JSZip();
const doi = location.pathname.split('/doi/')[1]?.replace(/\//g, '.') || 'wiley-supplements';
for (const url of selected) {
try {
const fileName = getFileName(url);
const res = await fetch(url, { mode: 'cors' });
const blob = await res.blob();
zip.file(fileName, blob);
} catch (e) {
console.warn('文件获取失败:', url, e);
}
}
zip.generateAsync({ type: 'blob' }).then(blob => {
saveAs(blob, `补充材料_${doi}.zip`);
downloadBtn.textContent = '✅ 打包下载完成';
setTimeout(() => {
downloadBtn.textContent = '✅ 打包下载选中文件';
downloadBtn.disabled = false;
}, 2000);
});
};
}
// 轮询检测异步加载的链接
function checkLinks() {
const supplementLinks = Array.from(document.querySelectorAll('a[href*="action/downloadSupplement?doi="]'));
if (supplementLinks.length > 0) {
createPanel(supplementLinks);
return true;
}
return false;
}
// 初次检测 + 定时轮询
if (!checkLinks()) {
const timer = setInterval(() => {
if (checkLinks()) {
clearInterval(timer);
}
}, 800);
}
})();
PDF的下载单位、IP信息已删除
(2025-6-4)