Wos Download Bot

wos核心论文集下载机器人

// ==UserScript==
// @name         Wos Download Bot
// @namespace    http://tampermonkey.net/
// @version      1.4.1
// @description  wos核心论文集下载机器人
// @author       AngelLiang
// @match        https://www.webofscience.com/wos/woscc/summary/*/relevance/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=webofscience.com
// @require      https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js
// @require      https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js
// @require      https://code.jquery.com/ui/1.13.0/jquery-ui.min.js
// @grant        GM_download
// @connect      *
// @license      MIT
// ==/UserScript==


(function() {
    'use strict';

    const DOWNLOAD_URL = "https://www.webofscience.com/api/wosnx/indic/export/saveToFile";

    var total = "";
    // 论文集的唯一码
    var uuid = ""
    // wos的唯一码(?)
    var wosSid = ""
    // 等待秒数
    var waitSecond = 30
    var fileFormat = ''

    function getTotal() {
        total = $(".brand-blue").text()
        total = total.replace(",", "")
        total = parseInt(total)
        return total
    }

    // 获取期刊的uuid
    function getParentQid() {
        let currUrl = String(window.location.href);
        return currUrl.split('/')[6]
    }

    function get_bm_telemetry() {
        // return bmak['sensor_data']
        // update: 20230709修改接口
        return bmak.get_telemetry()
    }

    function get_fileOpt() {
        if (fileFormat == 'excel') {
            return "xls"
        } else if (fileFormat == 'ris') {
            return "othersoftware"
        } else if (fileFormat == 'bibtex'){
            return "othersoftware"
        } else {
            return "othersoftware"
        }
    }

    function get_action() {
        if (fileFormat == 'excel') {
            return "saveToExcel"
        } else if (fileFormat == 'ris') {
            return "saveToRIS"
        } else if (fileFormat == 'bibtex'){
            return "saveToBibtex"
        } else {
            return "saveToFieldTagged"
        } 
    }

    function get_filters() {
        if (fileFormat == 'excel') {
            return "fullRecord"
        } else if (fileFormat == 'ris') {
            return "fullRecord"
        } else if (fileFormat == 'bibtex'){
            return "fullRecordPlus"
        } else {
            return "fullRecordPlus"
        } 
    }

    function getDownloadFileExt() {
        if (fileFormat == 'excel') {
            return ".xls"
        } else if (fileFormat == 'ris') {
            return ".ris"
        } else if (fileFormat == 'bibtex'){
            return ".bib"
        } else {
            return ".txt"
        } 
    }

    function genRequestData(start, stop) {
        let requestJson = {
            "parentQid": getParentQid(),
            "sortBy": "relevance",
            "displayTimesCited": "true",
            "displayCitedRefs": "true",
            "product": "UA",
            "colName": "WOS",
            "displayUsageInfo": "true",
            "fileOpt": get_fileOpt(),
            "action": get_action(),
            "markFrom": start,
            "markTo": stop,
            "view": "summary",
            "isRefQuery": "false",
            "locale": "en_US",
            "filters": get_filters(),
            // update: 20231211 不再需要这个字段
            // "bm-telemetry": get_bm_telemetry()
        }
        let requestData = JSON.stringify(requestJson)
        return requestData
    }

    function downloadFile(fileName, content) {
        let downLink = document.createElement('a')
        downLink.download = fileName
        //字符内容转换为blod地址
        let blob = new Blob([content])
        downLink.href = URL.createObjectURL(blob)
        // 链接插入到页面
        document.body.appendChild(downLink)
        downLink.click()
        // 移除下载链接
        document.body.removeChild(downLink)
    }

    function sleep(delay) {
        for(var t = Date.now(); Date.now() - t <= delay;);
    }

    // 生成随机数
    function randomNum(minNum, maxNum){
        switch(arguments.length){
            case 1:
                return parseInt(Math.random()*minNum+1,10);
            case 2:
                return parseInt(Math.random()*(maxNum-minNum+1)+minNum,10);
            default:
                return 0;
        }
    }

    function enableDownloadButton(){
        $("#downloadButton").html('一键下载')
        $("#downloadButton").attr("disabled", false);
    }

    function disableDownloadButton(){
        $("#downloadButton").html('正在下载...')
        $("#downloadButton").attr("disabled", true);
    }

    function requestFileByIndex(start, stop, total, callback) {
        start = "" + start;
        if (parseInt(stop) > total) {
            stop = total;
        }
        stop = "" + stop;

        console.log("正在下载" + start + "到" + stop + "份数据,总共" + total + "份")
        disableDownloadButton()
        try {
            var data = genRequestData(start, stop)    
        } catch (error) {
            console.error(error)
            enableDownloadButton()
            alert('请求出错,请联系开发者')
            return
        }

        let reqAjax = $.ajax({
            url:DOWNLOAD_URL,
            type: 'POST',
            headers: {
                "x-1p-wos-sid": wosSid,
                "accept": "application/json, text/plain, */*",
                "content-type": "application/json",
                "accept-language": "zh-CN,zh;q=0.9"
            },
            "crossDomain": true,
            data: data,
            success: function(result){
                //console.log(result);
                let filename = "" + start + '-' + stop + getDownloadFileExt()
                downloadFile(filename, result)
            },
            error: function(err){
                console.log(err);
                console.log(err.responseJSON);
                enableDownloadButton()
                alert('下载出错:'+JSON.stringify(err.responseJSON))
            }
        })

        $.when(reqAjax).done(function(){
            var nextStart = parseInt(start) + 500
            var nextStop = parseInt(stop) + 500
            if (nextStart > total) {
                enableDownloadButton()
                console.log("===下载完成===");
                alert('下载完成')
                return
            }
            let min_val = waitSecond - 5
            let max_val = waitSecond + 5
            var sleepNum = randomNum(min_val, max_val)
            console.log("等待" + sleepNum + "秒后再下载")
            sleep(sleepNum*1000)
            callback(nextStart, nextStop, total, callback)
        })
    }

    function getSessionID() {
        // const sidRegex = /SID=([a-zA-Z0-9]+)/i;

        // // session ID is embedded in the static page inside an inline <script>
        // // if you have the right HttpOnly cookie set. if we can't find it, we
        // // initialize our session as the web app does
        // for (let scriptTag of document.querySelectorAll('script')) {
        //     let sid = scriptTag.textContent.match(sidRegex);
        //     if (sid) {
        //         return sid[1];
        //     }
        // }
        // return null

        return sessionData.BasicProperties.SID
    }

    // 创建弹窗的函数
    function createPopup() {
        // 创建弹窗的容器
        var popupContainer = document.createElement('div');
        popupContainer.style.position = 'fixed';
        popupContainer.style.top = '50%';
        popupContainer.style.left = '50%';
        popupContainer.style.transform = 'translate(-50%, -50%)';
        popupContainer.style.background = '#fff';
        popupContainer.style.padding = '20px';
        popupContainer.style.border = '1px solid #ccc';
        popupContainer.style.zIndex = '9999';
    
        // 添加设置选项到弹窗
        // bug: 下载的excel还有点问题
        popupContainer.innerHTML = `
        <h3>一键下载</h3>
        <label for="fileFormat">文件格式:</label>
        <select id="fileFormat">
            <option value="ris">RIS</option>
            <option value="bibtex">BibTeX</option>
            <option value="txt">txt</option>
        </select><br>
        <label for="startDownloadFrom">起始下载份数:</label>
        <input type="text" id="startDownloadFrom" value="1"><br>
        <label for="downloadSpeed">下载速率(单位秒):</label>
        <input type="text" id="downloadSpeed" value="30"><br>
        <button id="confirmButton">开始下载</button>
        <button id="cancelButton">取消</button>
        `;
    
        // 确定下载按钮的点击事件处理
        var confirmButton = popupContainer.querySelector('#confirmButton');
        confirmButton.addEventListener('click', function() {
            waitSecond = parseInt(document.querySelector('#downloadSpeed').value);
            fileFormat = document.querySelector('#fileFormat').value;
            var start = parseInt(document.querySelector('#startDownloadFrom').value);

            // 进行下载操作
            console.log("开始下载")
            wosSid = getSessionID()
            uuid = getParentQid()
            var total = getTotal()

            console.log('下载速率:', waitSecond)
            console.log('文件格式:', fileFormat)
            console.log('起始下载份数:', start)
            console.log('wosSid:', wosSid)
            console.log('uuid:', uuid)
            console.log('总数:', total)

            var stop = start + 500 - 1

            // 校验
            if (waitSecond < 20){
                alert('下载速率不能太快')
                return
            }
            if (start > total) {
                alert('超过下载总数')
                return
            }

            requestFileByIndex(start, stop, total, requestFileByIndex)
            // 移除弹窗
            document.body.removeChild(popupContainer);
        });
    
        // 取消按钮的点击事件处理
        var cancelButton = popupContainer.querySelector('#cancelButton');
            cancelButton.addEventListener('click', function() {
            console.log("取消下载")
            // 移除弹窗
            document.body.removeChild(popupContainer);
        });
    
        // 将弹窗添加到页面
        document.body.appendChild(popupContainer);
    }

    function downloadCallback() {
        createPopup();
    }

    function initButton() {
        $('body').append('<button id="downloadButton">一键下载</button>')
        $('#downloadButton').css('width', '120px')
        $('#downloadButton').css('position', 'absolute')
        $('#downloadButton').css('top', '120px')
        $('#downloadButton').css('right', '50px')
        $('#downloadButton').css('background-color', '#5e33bf')
        $('#downloadButton').css('color', 'white')
        $('#downloadButton').css('font-size', 'large')
        $('#downloadButton').css('z-index', 100)
        $('#downloadButton').css('border-radius', '5px')
        $('#downloadButton').css('text-align', 'center')

        $('#downloadButton').click(downloadCallback)

        // 将按钮添加到页面
        // document.body.appendChild(downloadButton);
    };

    // 检查URL并初始化按钮
    function checkAndInitButton() {
        if (window.location.href.includes('https://www.webofscience.com/')) {
            initButton();
        }
    }

    $(document).ready(function () {
        console.log("WDB-v1.4.1")
        checkAndInitButton();
    })

})();