// ==UserScript==
// @name 中国知网CNKI硕博论文PDF下载
// @version 2.0.0
// @namespace https://greasyfork.org/users/244539
// @icon https://www.cnki.net/favicon.ico
// @description 知网文献、硕博论文批量下载,下载论文章节目录,阅读页面体验增强
// @author zoglmk
// @match http*://*.cnki.net
// @match http*://cdmd.cnki.com.cn/Article/CDMD-*
// @match http*://*/kcms/detail/detail.aspx?*dbcode=*
// @match http*://*/*/*/kcms/detail/detail.aspx?*dbcode=*
// @match http*://*/*/*/kcms/detail*
// @match http*://*/https/*/kcms*
// @match http*://*/KCMS/detail/detail.aspx?*dbcode=*
// @match http*://*/kns*/defaultresult/index*
// @match http*://*/https/*/kns8/defaultresult/index
// @match http*://*/https/*/kcms/detail/detail.aspx?
// @match http*://*/KNS8/AdvSearch?*
// @match http*://*/kns8/AdvSearch?*
// @match http*://*/kns/brief/*result*
// @match http*://*/kcms/Detail/DownDetail.aspx*
// @match http*://*/KNS8/DefaultResult/index*
// @match http*://*/kns8/DefaultResult/Index*
// @match http*://*/kns8/defaultresult/index*
// @match http*://*/https/*/KNS8/DefaultResult/*
// @match http*://*/kcms2/article/abstract?*
// @match http*://libproxy.wmu.edu.cn/*
// @match *://kns.cnki.net/KXReader/Detail?*
// @match *://new.oversea.cnki.net/KXReader/Detail?*
// @match *://new.big5.oversea.cnki.net/KXReader/Detail?*
// @match *://new.gb.oversea.cnki.net/KXReader/Detail?*
// @match *://*/KXReader/Detail?*
// @run-at document-idle
// @grant unsafeWindow
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_xmlhttpRequest
// @license MIT
// ==/UserScript==
//搜索页
var $ = unsafeWindow.jQuery;
(function() {
function loadCss(code){ // 加载CSS
var style = document.createElement('style');
style.type = 'text/css';
style.rel = 'stylesheet';
style.appendChild(document.createTextNode(code));
var head = document.getElementsByTagName('head')[0];
head.appendChild(style);
}
function createLoading(text, duration) {
var loadingContent = document.createElement('div');
loadingContent.style.cssText = 'position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);text-align:center;color:#333;font-size:16px;width:400px;height:40px;line-height:40px;z-index:9999;border:1px solid #0f5de5;padding:5px;background-color:#fff';
var loadingText = document.createElement('p');
loadingText.textContent = text;
loadingContent.appendChild(loadingText);
loadingContent.appendChild(loadingText);
document.body.appendChild(loadingContent);
setTimeout(() => {
document.body.removeChild(loadingContent);
}, duration);
return loadingContent;
}
function createPopupButton() {
var resultConL = document.querySelector('.result-con-l');
var popupButton = document.createElement('button');
popupButton.innerHTML = '批量下载PDF';
popupButton.style.cssText = 'display: inline-block;vertical-align: middle;padding: 2px 8px;margin-left: 5px;line-height: 18px;color: #0f5de5;font-size: 12px;text-align: center;background-color: #e3ecfd;border: 1px solid #fff;';
popupButton.addEventListener('click', createPopup);
//resultConL.appendChild(popupButton);
if(resultConL){resultConL.appendChild(popupButton);}
}
function createPopup() {
if (document.getElementById('popup')) {
return;
}
var popup = document.createElement('div');
popup.id = 'popup';
popup.style.cssText = 'position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 9999;';
var content = document.createElement('div');
content.style.cssText = 'height: 400px; overflow-y: scroll;width: 80%;position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);';
var closeButton = document.createElement('button');
closeButton.innerHTML = '关闭';
closeButton.className = 'diy-btn';
closeButton.addEventListener('click', function() {
document.body.removeChild(popup);
});
var linkButton = document.createElement('button');
linkButton.innerHTML = '获取链接';
linkButton.className = 'diy-btn';
linkButton.addEventListener('click', function() {
const table = document.querySelector('#my-table');
if (table.rows.length > 1) {
createLoading('已有数据!关闭弹窗后打开可重新获取!',2000);
} else {
getLinks();
}
});
var selectAllButton = document.createElement('button');
selectAllButton.innerHTML = '全选';
selectAllButton.className = 'diy-btn';
selectAllButton.addEventListener('click', selectAll);
var deselectAllButton = document.createElement('button');
deselectAllButton.innerHTML = '取消全选';
deselectAllButton.className = 'diy-btn';
deselectAllButton.addEventListener('click', deselectAll);
var downloadButton = document.createElement('button');
downloadButton.innerHTML = '下载';
downloadButton.className = 'diy-btn';
downloadButton.addEventListener('click', downloadSelected);
var selectCount = document.createElement('span');
selectCount.innerHTML = '已选择: 0';
selectCount.className = 'diy-btn';
var tips = document.createElement('span');
tips.innerHTML = '获取链接后请不要关闭窗口,否则链接会消失!';
tips.className = 'diy-btn';
tips.style.color = 'red';
var tips2 = document.createElement('span');
tips2.innerHTML = '如果获取失败或超时,请关闭窗口重新获取。';
tips2.className = 'diy-btn';
tips2.style.color = '#0b1f64';
content.appendChild(closeButton);
content.appendChild(linkButton);
content.appendChild(selectAllButton);
content.appendChild(deselectAllButton);
content.appendChild(downloadButton);
content.appendChild(selectCount);
content.appendChild(tips);
content.appendChild(tips2);
var table = document.createElement('table');
table.id = 'my-table';
table.style.cssText = 'margin-top:10px;';
table.innerHTML = '<thead><tr><th style="width:2%">多选</th><th style="width:3%">序号</th><th style="width:66%">名称</th><th style="width:8%">链接</th><th>分区</th></tr></thead><tbody></tbody>';
content.appendChild(table);
popup.appendChild(content);
document.body.appendChild(popup);
}
function selectAll() {
var selectItems = document.querySelectorAll('.selectItem');
for (var i = 0; i < selectItems.length; i++) {
selectItems[i].checked = true;
}
updateSelectCount();
}
function deselectAll() {
var selectItems = document.querySelectorAll('.selectItem');
for (var i = 0; i < selectItems.length; i++) {
selectItems[i].checked = false;
}
updateSelectCount();
}
function downloadSelected() {
var selectItems = document.querySelectorAll('.selectItem:checked');
var selectCount = selectItems.length;
if (selectCount === 0) {
createLoading('请选择要下载的项目!',2000);
return;
}
// 执行下载操作
selectItems.forEach((checkbox) => {
const link = checkbox.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.firstChild;
const url = link.getAttribute('href');
downloadFile(url);
});
}
function updateSelectCount() {
var selectCount = document.querySelectorAll('.selectItem:checked').length;
document.querySelector('#popup span').innerHTML = '已选择: ' + selectCount;
}
function downloadFile(url) {
window.open(url,'_blank')
}
function getLinks() {
const links = Array.from(document.querySelectorAll('.fz14')).map(link => link.href);
const loading = createLoading('获取链接(3-5秒,视网络状况而定)……',15000);
document.body.appendChild(loading);
Promise.all(links.map(link => fetch(link).then(response => response.text())))
.then(responses => {
const documents = responses.map(html => new DOMParser().parseFromString(html, 'text/html'));
const table = document.querySelector('#my-table');
let selectedCount = 0;
let index = table.querySelectorAll('tr').length;
documents.forEach((doc, i) => {
const title = doc.querySelector('.wx-tit')?.firstElementChild.textContent || '无标题';
const author = doc.querySelectorAll('.author');
const pdfLink = doc.querySelector('#pdfDown')?.href || '无链接';
const label_data = [];
const label_area = doc.querySelectorAll('.type');
const author_texts = [];
author.forEach(a => {
author_texts.push(a.textContent);
});
const a = author_texts.join(' ');
label_area.forEach((label, i) => {
label_data.push('<span class="diy-btn">'+label.textContent+'</span>');
})
const title_data = ['<span class="diy_title">'+title+'</span>','<span class="diy_author">'+a+'</span>'];
const l = label_data.join('');
const t = title_data.join('');
const row = document.createElement('tr');
if(pdfLink == '无链接'){
row.innerHTML = '<td><input type="checkbox" class="selectItem"></td><td style="text-align:center">' + (i+1) + '</td><td>' + t + '</td><td><a href="javascript:;">获取链接失败!</a></td><td>'+l+'</td>';
}else{
row.innerHTML = '<td><input type="checkbox" class="selectItem"></td><td style="text-align:center">' + (i+1) + '</td><td>' + t + '</td><td><a href="'+pdfLink+'" target="_blank" class="diy-btn">PDF下载</a></td><td>'+l+'</td>';
}
table.querySelector('tbody').appendChild(row);
const input = row.querySelector('input[type="checkbox"]');
input.addEventListener('change', () => {
if (input.checked) {
updateSelectCount();
} else {
updateSelectCount();
}
});
});
document.body.removeChild(loading);
createLoading('获取完毕!',2000);
})
.catch(error => {
document.body.removeChild(loading);
createLoading(`获取链接出错:${error.message}`,3000);
});
}
createPopupButton();
loadCss(`
.diy-btn {display: inline-block;vertical-align: middle;padding: 2px 8px;margin-left: 5px;line-height: 18px;color: #0f5de5;font-size: 12px;text-align: center;background-color: #e3ecfd;border: 1px solid #fff;}
#popup table tr td,#popup table tr th {line-height: 20px;height: 20px;padding: 5px;border: 1px solid #eee;}
.diy_title {display: block;color: #524d4d;font-size: 14px;font-weight: bold;}
.diy_author {color:#666}
`);
})();
(function() {
function saveFile(name,data) { // 生成目录txt
const blob = new Blob([data],{type:'text/plain'});
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = name + ".txt";
link.click();
window.URL.revokeObjectURL(link.href);
}
function add_cate_dl_btn() { // 添加目录下载按钮
var other_btns = document.getElementsByClassName('other-btns')[0];
var li2 = document.createElement('li');
var a2 = document.createElement('a');
li2.className = "btn-diy";
li2.style = "width:auto;height:23px;line-height:22px;background-color:#3f8af0;border-radius:3px;";
a2.innerHTML = "目录下载";
a2.className = "a-diy";
a2.style = "color:#ffffff;padding: 2px 10px;";
a2.href = "javascript:void(0)";
li2.appendChild(a2);
other_btns.appendChild(li2);
}
function get_cate(hrefLink){
var r = {};
fetch(hrefLink)
.then(response => response.text())
.then(data => {
const html = new DOMParser().parseFromString(data, 'text/html');
const title = html.querySelector('.title').textContent;
r.title = title;
const chapterList = html.querySelector('.ls-chapters').querySelectorAll('li');
const chapterTextList = [];
chapterList.forEach((chapter) => {
const text = chapter.textContent.trim();
if (text) {
chapterTextList.push(text);
}
});
const result = chapterTextList.map(item => {
const text = item.replace(/[\n]/g, ' ');
if (text.includes("-")) {
var text_res = text.split("-")[0];
}else{text_res = text}
return `${text_res} \n`;
}).join('');
// 输出结果
r.result = result;
});
return r;
}
var url = window.location.href;
if(url.includes("abstract") || url.includes("detail.aspx")){
add_cate_dl_btn(); // 添加目录下载按钮
const operateBtn = document.querySelector('.operate-btn');
const liElement = operateBtn.querySelector('li:nth-child(5)');
const hrefLink = liElement.querySelector('a').href;
var r = get_cate(hrefLink);
console.log(r);
$(document).on("click",".a-diy",function(){
saveFile(r.title,r.result);
}); // 下载目录按钮监听
}
})();
(function() {
'use strict';
function loadCss(code){ // 加载CSS
var style = document.createElement('style');
style.type = 'text/css';
style.rel = 'stylesheet';
style.appendChild(document.createTextNode(code));
var head = document.getElementsByTagName('head')[0];
head.appendChild(style);
}
window.onload = function(){
function changeFontSize(action) {
var main = document.getElementsByClassName('main')[0];
var cur_size = window.getComputedStyle(main).fontSize.replace("px", "") - 0;
if (action === "increase") {
main.style.fontSize = (cur_size + 1) + "px";
} else if (action === "decrease") {
main.style.fontSize = (cur_size - 1) + "px";
}
var ps = main.getElementsByClassName('p1');
for (var i = 0; i < ps.length; i++) {
ps[i].style.fontSize = main.style.fontSize;
}
}
function change_mode(color){
localStorage.bgc=color;
var c_bgc = document.getElementsByTagName('body')[0];
var c_main = document.getElementsByClassName('main')[0];
var c_dl = document.getElementsByTagName('dl');
var c_p = document.getElementsByTagName('p');
var c_nav = document.getElementsByClassName('ecp_top-nav')[0];
var c_con = document.getElementsByClassName('content')[0];
var c_tips = document.getElementsByClassName('tips')[0];
var c_refer = document.getElementsByClassName('refer')[0];
var c_h4 = document.getElementsByClassName('refer')[0].getElementsByTagName('h4')[0];
var c_briefs = document.getElementsByClassName('brief');
c_bgc.style.backgroundColor = localStorage.bgc;
c_nav.style.backgroundColor = localStorage.bgc;
c_con.style.backgroundColor = localStorage.bgc;
c_tips.style.backgroundColor = localStorage.bgc;
c_main.style.background = localStorage.bgc;
c_refer.style.background = localStorage.bgc;
c_h4.style.background = localStorage.bgc;
for(var i=0;i<c_briefs.length;i++){
c_briefs[i].style.background = localStorage.bgc;
}
for(var j=0;j<c_dl.length;j++){
c_dl[j].style.backgroundColor = localStorage.bgc;
}
for(var m=0;m<c_p.length;m++){
c_p[m].style.backgroundColor = localStorage.bgc;
}
}
function change_mode_auto(){
change_mode(localStorage.bgc);
var select_default = document.getElementById("protect_eyes_select");
for(var i=0; i<select_default.options.length; i++){
if(select_default.options[i].value == localStorage.bgc){
select_default.options[i].selected = true;
break;
}
}
}
function createButton(title, text, id, action) {
var button = document.createElement('span');
button.title = title;
button.id = id;
button.innerText = text;
button.className = "font-size-button";
button.onclick = action;
return button;
}
var font_size_button_plus = createButton("增大字体", "字✚", "font_size_button_plus",function() { changeFontSize("increase");});
font_size_button_plus.style.bottom = "-60px";
var font_size_button_redu = createButton("减小字体", "字 ━", "font_size_button_redu",function() { changeFontSize("decrease")});
font_size_button_redu.style.bottom = "-30px";
var protect_eyes = document.createElement('select');
protect_eyes.insertAdjacentHTML("beforeend",'<option value="none" selected>护眼模式</option><option value="#FFFFFF">银河白</option><option value="#FAF9DE">杏仁黄</option><option value="#FFF2E2">秋叶褐</option><option value="#FDE6E0">胭脂红</option><option value="#E3EDCD">青草绿</option><option value="#DCE2F1">海天蓝</option><option value="#E9EBFE">葛巾紫</option><option value="#EAEAEF">极光灰</option>');
protect_eyes.style.width="36px";
protect_eyes.id="protect_eyes_select";
protect_eyes.style.fontSize="12px";
document.getElementsByClassName('backtop')[0].appendChild(protect_eyes);
document.getElementsByClassName('backtop')[0].appendChild(font_size_button_plus);
document.getElementsByClassName('backtop')[0].appendChild(font_size_button_redu);
document.getElementById("protect_eyes_select").addEventListener("change", function(){change_mode(this.value)});
change_mode_auto()
};
loadCss(`
.font-size-button { font-size: 14px; display: block; line-height: 18px; border: 1px solid #e2e2e2; border-radius: 2px; background-color: #f5f5f5; color: #504f4f; float: left; padding: 3px; position: absolute; right: 0; width: 28px;}
`);
})();