// ==UserScript== // @name ProQuest Document Downloader // @namespace http://tampermonkey.net/ // @version 0.1 // @license MIT // @description Download documents from ProQuest search results // @author powcai // @match https://www.proquest.com/* // @grant GM_xmlhttpRequest // @grant GM_addStyle // @run-at document-end // @connect * // @downloadURL none // ==/UserScript== (function() { 'use strict'; // 添加样式 GM_addStyle(` .download-all-btn { position: fixed; top: 20px; right: 20px; background-color: #4CAF50; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; z-index: 9999; } .single-download-btn { background-color: #2196F3; color: white; padding: 5px 10px; border: none; border-radius: 4px; cursor: pointer; margin: 5px; } .download-status { color: #666; margin-left: 10px; font-size: 12px; } `); // 下载单个文档 async function downloadDocument(downloadUrl, statusElement) { try { if (statusElement) { statusElement.textContent = '准备下载...'; } return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: 'GET', url: downloadUrl, responseType: 'blob', onload: function(response) { if (response.status === 200) { const blob = new Blob([response.response], { type: 'application/pdf' }); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `proquest-doc-${Date.now()}.pdf`; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); a.remove(); if (statusElement) { statusElement.textContent = '下载完成'; statusElement.style.color = '#4CAF50'; } resolve(); } else { if (statusElement) { statusElement.textContent = '下载失败: ' + response.status; statusElement.style.color = '#f44336'; } reject(new Error('下载失败: ' + response.status)); } }, onerror: function(error) { console.error('下载请求失败:', error); if (statusElement) { statusElement.textContent = '下载失败: 网络错误'; statusElement.style.color = '#f44336'; } reject(error); } }); }); } catch (error) { console.error('下载过程出错:', error); if (statusElement) { statusElement.textContent = '下载失败: ' + error.message; statusElement.style.color = '#f44336'; } throw error; } } // 添加下载按钮到每个搜索结果 function addDownloadButtons() { const resultItems = document.querySelectorAll('li.resultItem'); resultItems.forEach(item => { // 检查是否已经添加了下载按钮 if (item.querySelector('.single-download-btn')) { return; } const pdfLink = item.querySelector('a[href*="fulltextPDF"]'); if (!pdfLink) return; const buttonContainer = document.createElement('div'); buttonContainer.style.display = 'flex'; buttonContainer.style.alignItems = 'center'; const downloadBtn = document.createElement('button'); downloadBtn.className = 'single-download-btn'; downloadBtn.textContent = '下载文档'; const status = document.createElement('span'); status.className = 'download-status'; buttonContainer.appendChild(downloadBtn); buttonContainer.appendChild(status); item.appendChild(buttonContainer); downloadBtn.onclick = async () => { try { const pdfPageUrl = pdfLink.href; console.log("pdfPageUrl", pdfPageUrl) const response = await fetch(pdfPageUrl); const html = await response.text(); const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); const downloadLink = doc.querySelector('a.pdf-download[download="ProQuestDocument.pdf"]'); if (downloadLink) { await downloadDocument(downloadLink.href, status); } else { throw new Error('找不到PDF下载链接'); } } catch (error) { console.error('单个文档下载失败:', error); status.textContent = '下载失败: ' + error.message; status.style.color = '#f44336'; } }; }); } // 添加批量下载按钮 function addBatchDownloadButton() { if (document.querySelector('.download-all-btn')) { return; } const batchButton = document.createElement('button'); batchButton.className = 'download-all-btn'; batchButton.textContent = '批量下载全部'; document.body.appendChild(batchButton); batchButton.onclick = async () => { const resultItems = document.querySelectorAll('li.resultItem'); let delay = 0; for (const item of resultItems) { const pdfLink = item.querySelector('a[href*="fulltextPDF"]'); console.log(pdfLink) if (!pdfLink) continue; const status = item.querySelector('.download-status') || document.createElement('span'); status.className = 'download-status'; item.appendChild(status); setTimeout(async () => { try { const pdfPageUrl = pdfLink.href; const response = await fetch(pdfPageUrl); const html = await response.text(); const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); const downloadLink = doc.querySelector('a.pdf-download[download="ProQuestDocument.pdf"]'); if (downloadLink) { await downloadDocument(downloadLink.href, status); } else { throw new Error('找不到PDF下载链接'); } } catch (error) { console.error('批量下载过程中出错:', error); status.textContent = '下载失败: ' + error.message; status.style.color = '#f44336'; } }, delay); delay += 2000; // 每个下载间隔2秒 } }; } // 监听页面变化 const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { if (mutation.addedNodes.length) { addDownloadButtons(); addBatchDownloadButton(); } } }); // 初始化 function initialize() { addDownloadButtons(); addBatchDownloadButton(); observer.observe(document.body, { childList: true, subtree: true }); } // 页面加载完成后初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initialize); } else { initialize(); } })();