Greasy Fork is available in English.

中国知网CNKI硕博论文PDF下载

知网文献、硕博论文批量下载,下载论文章节目录,阅读页面体验增强

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==UserScript==
// @name         中国知网CNKI硕博论文PDF下载
// @version      2.0.2
// @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/*/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.replace(link.href.split("/")[2],document.querySelectorAll('.logo a')[0].baseURI.replace("https://",'').replace("kns8/defaultresult/index",'')));
        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,{method: 'GET',mode: 'same-origin',referrerPolicy: 'unsafe-url',}).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 || '无链接';
                // console.log(title,pdfLink);
                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;}
`);
})();