Greasy Fork is available in English.

全国图书馆参考咨询联盟

下载DPF少操作一步,「文章下载」替换成「PDF下载」,点击直接下载。也可辅助Zotero translator的Superlib.js,直接抓取PDF。

// ==UserScript==
// @name           全国图书馆参考咨询联盟
// @description    下载DPF少操作一步,「文章下载」替换成「PDF下载」,点击直接下载。也可辅助Zotero translator的Superlib.js,直接抓取PDF。
// @author         018(lyb018@gmail.com)
// @contributor    Rhilip
// @connect        *
// @grant          GM_xmlhttpRequest
// @grant          GM_setClipboard
// @grant          GM_addStyle
// @grant          GM_setValue
// @grant          GM_getValue
// @grant          GM_listValues
// @grant          GM_deleteValue
// @grant          GM_registerMenuCommand
// @require        https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js
// @require        https://greasyfork.org/scripts/368137-encodeToGb2312/code/encodeToGb2312.js?version=601683
// @include        http://jour.ucdrs.superlib.net/*
// @include        http://book.ucdrs.superlib.net/views/specific/*
// @version        0.2.1
// @run-at         document-end
// @namespace      http://018.ai
// ==/UserScript==

// This Userscirpt can't run under Greasemonkey 4.x platform
if (typeof GM_xmlhttpRequest === 'undefined') {
    alert('不支持Greasemonkey 4.x,请换用暴力猴或Tampermonkey')
    return
}

// 不属于的页面
if (!/ucdrs.superlib.net/.test(location.host)) {
    return
}

;(function () {
    'use strict';

    $(document).ready(function () {
        if (location.href.includes('book.ucdrs.superlib.net/views/specific')) {
            $('#libinfo .title').after($('<div class="box"><h3 class="boxHd">下载 </h3><div class="link" id="download"><span style="color:#989B9B">(...)</span></div> <div class="link" id="downloadTry"><span style="color:#989B9B">(...)</span></div></div>'));
            // 中图分类
            for(let dd of $('.tubox dl dd')) {
                if (dd.textContent.startsWith('【中图法分类号】')) {
                    let clcs = opt(opt(/【中图法分类号】.*/.exec(dd.textContent)).match(/[a-zA-Z0-9\.;]+/)).split(';');
                    var ddTextContent = dd.textContent;
                    for(let clc of clcs) {
                        ddTextContent = ddTextContent.replace(clc, '<a id="clc" target="_blank" href="http://uread.today/clc?c=' + clc + '">' + clc + '</a>') + ' <span id="clcText_' + clc.replace('.', '') + '">(...)</span>\n';
                        requestClc(clc, function(subject) {
                            appendsubject(subject, dd);
                        }, dd);
                    }
                    $(dd).html(ddTextContent)
                } else if (dd.textContent.startsWith('【ISBN号】')) {
                    let title = $('.tutilte').text();
                    let isbn = opt(/【ISBN号】.*/.exec(dd.textContent)).replace(/【ISBN号】|-|\n/g, '');

                    let intervalID = setInterval(function() {
                        requestBOK(title, isbn);
                        clearInterval(intervalID);
                    }, 1000);
                }
            }

            var as1 = $('.testimg a');
            if (as1.length == 0) {
                as1 = $('.link a');
            }
            if (as1.length > 0) {
                loadBookHref(as1.get(0));
            }
        } else if (location.href.includes('jour.ucdrs.superlib.net/views/specific')) {
            // 论文,文章下载
            setTimeout(function(){
                var as0 = $('.link a');
                if (as0.length > 0) {
                    loadJourHref(as0.get(0));
                }
            }, 1000);
        } else if (location.href.includes('jour.ucdrs.superlib.net/searchJour')) {
            // 文章下载
            for (var a of $('.book1 .get a')) {
                if (a.textContent != '文章下载') continue;

                loadJourHref(a);
            }
        }
    })

    // 加载试读页面
    function loadBookHref(a) {
        loadDoc(a.href, {a: a}, function(doc, responseDetail, meta) {
            let $assistUrl = $(doc.querySelector('#downpdf [name=assistUrl]'));
            let assistUrl = $assistUrl.attr('value');
            let $cntUrl = $(doc.querySelector('#downpdf [name=cntUrl]'));
            let cntUrl = $cntUrl.attr('value');

            $('#downloadTry').html('<a target="_blank" href="' + cntUrl + '">下载正文试读</a> <a target="_blank" href="' + assistUrl + '">下载目录页</a>');
        });
    }

    // 加载PDF页面
    function loadJourHref(a) {
        loadDoc(a.href, {a: a}, function(doc, responseDetail, meta) {
            var download = doc.querySelector('.download .down_bnt');
            if (download) {
                $(meta.a).attr('href', download.href);
                $(meta.a).html('PDF下载');
            }
        });
    }

    // 请求电子书
    function requestBOK(title, isbn) {
        loadDoc('https://b-ok.global/s/' + isbn, {title: title, isbn: isbn}, function(doc, responseDetail, meta) {
            let found = false;
            for (let a of doc.querySelectorAll('table.resItemTable h3[itemprop=name] a')) {
                if (a.textContent.includes(meta.title) || meta.title.includes(a.textContent)) {
                    let url = a.href.replace(location.host, 'b-ok.global').replace('http:', 'https:');
                    found = true;
                    loadDoc(url, {}, function(doc, responseDetail, meta) {
                        let addDownloadedBook = doc.querySelector('.addDownloadedBook');
                        if (addDownloadedBook) {
                            let txt = addDownloadedBook.textContent.match(/\(.*\)/g);
                            url = addDownloadedBook.href.replace(location.host, 'b-ok.global').replace('http:', 'https:');
                            if ($('#download').text() == '(...)') {
                                $('#download').html('<a target="_blank" href="' + url + '">下载' + txt + '</a>');
                            } else {
                                $('#download').append('<a target="_blank" href="' + url + '">下载' + txt + '</a>');
                            }
                        } else {
                            $('#download').html('<span style="color:#989B9B"> 暂无资源 </span>');
                        }
                    }, function(err, meta) {
                        $('#download').html('<span style="color:#989B9B"> 暂无资源 </span>');
                    });
                }
            }

            if (!found) {
                $('#download').html('<span style="color:#989B9B"> 暂无资源 </span>');
            }
        }, function(err, meta) {
            $('#download').html('<span style="color:#989B9B"> 暂无资源 </span>');
        });
    }

    // 请求istic,获取分类名称,备用,暂不启用。
    function requestClc(clc, subject, dd) {
        doGet('http://api.uread.today/master/anon/ch_lib_cls/info?code=' + clc, {dd: dd, clc: clc}, function(json, responseDetail, meta) {
            if (json.resultcode == 40000 && meta.clc.length > 0) {
                if (meta.clc.includes('.')) {
                    requestClc(meta.clc.replace(/\.\d*$/, ''), subject, meta.dd);
                } else {
                    requestClc(meta.clc.replace(/\d$/, ''), subject, meta.dd);
                }
                return;
            }

            let clcs = [];
            clcs.push(...json.data.clc.parents.map((e) => e.clc + ' ' + hanldeClcText(e.name)));
            clcs.push(json.data.clc.clc + ' ' + hanldeClcText(json.data.clc.name))
            htmlclc(clc, clcs, meta.dd);

            subject(json.data.subject)
        }, function(err, meta) {
            requestClcA(meta.clc, meta.dd);
        });
    }

    // 请求istic,获取分类名称,备用,暂不启用。
    function requestClcA(clc, dd) {
        doPost('https://ct.istic.ac.cn/site/clc/getByClassName?t=' + new Date().getTime(),
               { "Content-Type": "application/x-www-form-urlencoded" }, 'classname=' + clc, {dd: dd, clc: clc}, function(json, responseDetail, meta) {
            if (json.length == 0 && meta.clc.length > 0) {
                if (meta.clc.includes('.')) {
                    requestClcA(meta.clc.replace(/\.\d*$/, ''), meta.dd);
                } else {
                    requestClcA(meta.clc.replace(/\d$/, ''), meta.dd);
                }
                return;
            }

            let clcs = [];
            let jsonMap = {};
            let pid;

            let level;
            for (let i = 0; i < json.length; i ++) {
                if (clcs.length == 0 && json[i].classNum.split('/').includes(clc)) {
                    clcs.push(json[i].classNum + ' ' + hanldeClcText(json[i].className, meta.dd));

                    pid = json[i].pid;
                    level = json[i].level;
                } else if( json[i].level < level) {
                    jsonMap[json[i].id + ''] = json[i];
                }
            }

            clcText(meta.clc, pid, jsonMap, clcs, meta.dd);

            htmlclc(meta.clc, clcs, meta.dd);
        }, function(err, meta) {
            requestClcB(meta.clc, meta.dd);
        });
    }

    //  处理clc文字
    function clcText(clc, pid, jsonMap, rets, dd) {
        if (!jsonMap || !rets) return;

        if( jsonMap[pid] ) {
            rets.unshift(jsonMap[pid].classNum + ' ' + hanldeClcText(jsonMap[pid].className, dd));

            if (jsonMap[pid].level <= 2) return;

            clcText(clc, jsonMap[pid].pid, jsonMap, rets, dd);
        }
    }

    function htmlclc(clc, rets, dd) {
        if (rets.length > 0) {
            let clcText = $('#clcText_' + clc.replace('.', ''));
            if (clcText.text() == '(...)' ) {
                clcText.html('(' + rets.join('<span style="color:#989B9B"> ▸ </span>') + ')');
            }
        } else {
            let clcText = $('#clcText_' + clc.replace('.', ''));
            if (clcText.text() == '(...)' ) {
                clcText.html('<span style="color:#989B9B">(查无此信息)</span>');
            }
        }
    }

    function hanldeClcText(txt, dd) {
        var splits = txt.split(/、|(|)|\(|\)/);
        var retss = [];
        for (var s of splits) {
            if (s.length == 0) continue;

            retss.push(' <a target="_blank" href="http://uread.today/clc-subject?t=content&q=' + s + '">' + s + '</a>');

            //requestxhma(s, dd);
        }
        return retss.join('、');
    }

    // 请求clcindex,获取分类名称
    function requestClcB(clc, dd) {
        var url = 'https://www.clcindex.com/category/' + clc;
        loadDoc(url, {dd: dd, clc: clc, url: url}, function(doc, responseDetail, meta) {
            let clcs = [];
            for (let li of doc.querySelectorAll('.breadcrumb li.active')) {
                if (!li) continue;

                var txtContent = li.textContent.trim();
                var clcCode;
                var index = txtContent.indexOf(' ');
                if (index > 0) {
                    clcCode = txtContent.substr(0, index);
                    txtContent = txtContent.substr(index + 1);
                }

                clcs.push(clcCode + ' ' + hanldeClcText(txtContent, meta.dd));
            }

            $('#clc').attr('href', meta.url);
            htmlclc(clcs);
        }, function(err, meta) {
            if (err.status == 404) {
                if (meta.clc.includes('.')) {
                    requestClcB(meta.clc.replace(/\.\d*$/, ''), meta.dd);
                } else {
                    requestClcB(meta.clc.replace(/\d$/, ''), meta.dd);
                }
                return;
            }

            let clcText = $('#clcText_' + meta.clc);
            if (clcText.text() == '(...)' ) {
                clcText.html('<span style="color:#989B9B">(无法获取)</span>');
            }
        });

    }

    // 请求xhma,获取学科
    function requestxhma(s, dd) {
        var url = 'http://xkfl.xhma.com/search?w=' + s;
        loadDoc(url, {dd: dd}, function(doc, responseDetail, meta) {
            let spans = doc.querySelectorAll('.data li:not(.t) span');//code
            if (spans.length == 1) {
                let name = spans[0].nextElementSibling.textContent.trim();
                if (name.includes(s)) {
                    let code = spans[0].textContent.trim();
                    appendsubject(' <a target="_blank" href="' + spans[0].nextElementSibling.href + '">' + code + ' ' + name + '</a>', meta.dd);
                }
            } else if (spans.length > 1) {
                for (let span of spans) {
                    if (!span) continue;

                    let name = span.nextElementSibling.textContent.trim();
                    if (name != s && (name != s + '学')) continue;

                    let code = span.textContent.trim();

                    appendsubject('<a target="_blank" href="' + span.nextElementSibling.href + '">' + code + ' ' + name + '</a>', meta.dd);
                }
            }
        }, function(err, meta) {
        });
    }

    function appendsubject(subject, dd) {
        let clcText = $('#subjectText');
        let subjectText = ' <a target="_blank" href="http://uread.today/subject?c=' + subject.code + '">' + subject.code + ' ' + subject.name + '</a>'
        if (clcText.length == 0) {
            $(dd).after($(' \n<dd >【学科分类号】<span id="subjectText"><span id="subject" style="display: none;">' + subject.code + '</span><span>' + subjectText + '</span></span></dd>'));
        } else {
            clcText.append('<span style="color:#989B9B"> | </span><span>' + subjectText + '</span>');
        }
    }

    // 判断,空返回空字符串
    function opt(val) {
        if (!val) return '';

        if (val instanceof Array) {
            if (val.length > 0) {
                return val[0];
            }
        } else {
            return val;
        }
    }

    // 对使用GM_xmlhttpRequest返回的html文本进行处理并返回DOM树
    function page_parser(responseText) {
        // 替换一些信息防止图片和页面脚本的加载,同时可能加快页面解析速度
        responseText = responseText.replace(/s+src=/ig, ' data-src='); // 图片,部分外源脚本
        responseText = responseText.replace(/<script[^>]*?>[\S\s]*?<\/script>/ig, ''); //页面脚本
        return (new DOMParser()).parseFromString(responseText, 'text/html');
    }

    // 加载网页
    function loadDoc (url, meta, callback, fail) {
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            onload: function (responseDetail) {
                if (responseDetail.status === 200) {
                    let doc = page_parser(responseDetail.responseText)
                    callback(doc, responseDetail, meta)
                } else if (fail){
                    fail(responseDetail, meta);
                }
            },
            onerror: function(err) {
                if (fail) {
                    fail(err, meta);
                }
            }
        })
    }

    // get请求
    function doGet (url, meta, callback, fail) {
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            onload: function (responseDetail) {
                if (responseDetail.status === 200) {
                    callback(JSON.parse(responseDetail.responseText), responseDetail, meta)
                } else if (fail){
                    fail(responseDetail, meta);
                }
            },
            onerror: function(err) {
                if (fail) {
                    fail(err, meta);
                }
            }
        })
    }

    // post请求
    function doPost (url, headers, data, meta, callback, fail) {
        GM_xmlhttpRequest({
            method: "POST",
            url: url,
            data: data,
            headers: headers,
            onload: function(responseDetail){
                if (responseDetail.status === 200) {
                    callback(JSON.parse(responseDetail.responseText), responseDetail, meta)
                } else if (fail){
                    fail(responseDetail, meta);
                }
            },
            onerror: function(err) {
                if (fail) {
                    fail(err, meta);
                }
            }
        })
    }
})()

// 测试URL
// http://jour.ucdrs.superlib.net/searchJour?sw=%E6%85%A2%E6%80%A7&allsw=%23%2Call%E9%95%BF%E6%97%B6&bCon=&ecode=utf-8&channel=searchJour&Field=all