hacker emblem Song Ziming's Blog

在中国知网下载 PDF 格式的学位论文

因为要写毕设论文,需要查阅许多知网上的学位论文。而中国知网奇怪的地方在于,放着成熟的 PDF 规范不用,非要自己搞出一个封闭的 CAJ 格式,学位论文还不提供 PDF 的格式,逼着人们只能去下载它们的 CAJViewer,最不可忍受的是竟然没有 Linux 下的版本!

但是群众的智慧是无穷的,最近发现,通过一个 UserScript 就可以给学位论文页面加上“PDF 下载”的按钮。

所谓 UserScript,就是一个浏览器插件,能够动态地修改页面内容。在 Chrome 浏览器中,需要安装 Tampermonkey 插件来管理 UserScripts,FireFox 中可以使用 Greasemonkey。

脚本的内容可以从这里获取。原本的域名是 userscripts.org,但这个网站似乎挂了很久了,不过镜像站 userscripts-mirror.org 一直可用。

代码

为了保险,将脚本完整内容复制在此:

// ==UserScript==
// @id             CNKI-PDF-Special
// @name           CNKI 中国知网 PDF 全文下载(特制版)
// @version        1.25
// @namespace      http://yuelong.info
// @author         YUE Long
// @updateURL      https://userscripts.org/scripts/source/164338.meta.js
// @description    ① 点击 CNKI 检索结果界面中的下载按钮可以直接下载 PDF 格式文献;
//                 ② 在硕士/博士学位论文详细信息界面添加“PDF下载”按钮。
//                 ※ 特制版功能:在检索页面中的硕士/博士论文默认下载 CAJ 文件。
// @include        http://*.cnki.net/*
// @include        http://*.cnki.net.*/*
// @run-at         document-idle
// ==/UserScript==

var allLis, thisLi, newLi, aPDF, allLinks, thisLink, pageType;
pageType = true;

allLinks = document.evaluate(
    '//a[@href]',
    document,
    null,
    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
    null);

allLis = document.evaluate(
    "//li[@class]",
    document,
    null,
    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
    null);

if (allLis) {
    for (var i = 0; i < allLis.snapshotLength; i++) {
        thisLi = allLis.snapshotItem(i);
        if (thisLi.getAttribute("class").indexOf("readol") !== -1) {
            pageType = false;
            newLi = document.createElement('li');
            newLi.setAttribute("class","pdf");
            aPDF = '<a target="_blank" href="' +
                   thisLi.firstChild.href.replace("&dflag=readonline","&dflag=pdfdown") +
                   '">PDF下载</a>';
            newLi.innerHTML=aPDF;
            thisLi.parentNode.insertBefore(newLi, thisLi.nextSibling);
        }
        if (thisLi.getAttribute("class").indexOf("cajNew") !== -1) {
            pageType = false;
        }
    }
}

if (pageType) {
    for (var i = 0; i < allLinks.snapshotLength; i++) {
        thisLink = allLinks.snapshotItem(i);
        if (thisLink.href &&
            thisLink.href.indexOf("download.aspx?filename=") != -1 &&
            thisLink.href.indexOf("&dflag") == -1 &&
            thisLink.href.indexOf("=CMFD") == -1 &&
            thisLink.href.indexOf("=CDFD") == -1
        ) {
            thisLink.href = thisLink.href + "&dflag=pdfdown";
        }
        if (thisLink.href &&
            thisLink.href.indexOf("download.aspx?filename=") != -1 &&
            thisLink.href.indexOf("&dflag") == -1 &&
            (thisLink.href.indexOf("=CMFD") !== -1 || thisLink.href.indexOf("=CDFD") !== -1 )
        ) {
            thisLink.href = thisLink.href + "&dflag=nhdown";
        }
    }
}

把这段代码添加到 Tampermonkey 中,再访问知网,点开一个学位论文的页面,就能从上面看到“PDF 下载”的按钮了。就像这样:

学位论文可以下载 PDF 格式

关于 UserScript

UserScript 就是一段 JavaScript 代码,当一个页面加载完成之后,这段 JavaScript 就会自动执行,效果就和在调试工具的终端里执行 JavaScript 一样。因此,UserScript 能够访问操作 DOM 节点,能使用页面引用的所有库。

UserScript 通常由浏览器的插件来管理,例如 FireFox 有 Greasemonkey,Webkit/Blink 内核的浏览器则有 Tampermonkey,而且这些工具支持的 UserScript 接口相同,同样的 UserScript 在不同的管理插件下执行的效果也是一致的。

至于代码开头的那一段注释,其实就是这个 UserScript 的元数据,其中描述了代码的名称、版本、作者,以及作用于哪些网页等等。

这里是上面这段UserScript的原始出处。

P.S. 这段代码实现 PDF 下载的原理并不高深,只是修改了下载链接,改了一些 GET 参数。因此可以推断,CAJ 格式实际上与 PDF 非常相似,知网的服务器可以实现格式的转换。这样转出来的 PDF 是文字版,虽然没有 CAJ 中的目录,基本需求已经完全满足。