CNKI保存结果页面

在页面右下角以图标的形式展示获取页面的原始数据,并在点击图标时将数据保存到本地文件中。

当前为 2024-09-18 提交的版本,查看 最新版本

// ==UserScript==
// @name         CNKI保存结果页面
// @version      1.3
// @description  在页面右下角以图标的形式展示获取页面的原始数据,并在点击图标时将数据保存到本地文件中。
// @match        https://kns.cnki.net/kns8s/search*
// @match        https://kns.cnki.net/kns8s/defaultresult/index*
// @grant        GM_registerMenuCommand
// @grant        GM_xmlhttpRequest
// @grant        GM_download
// @namespace https://greasyfork.org/users/1237542
// ==/UserScript==

var executeScript = false;

function main() {
  if (executeScript) {
    var rows = document.querySelectorAll('tbody tr');
    var data = [];

    for (var i = 0; i < rows.length; i++) {
      var row = rows[i];
      var titleElement = row.querySelector('.name a.fz14');
      var title = ''; // 标题默认为空字符串
      var link = '';

      /*if (titleElement) {
        title = titleElement.textContent.trim(); // 获取标题文本
        link = titleElement.href; // 获取链接
      }*/
      if (titleElement) {
        title = sanitizeTitle(titleElement.textContent.trim()); // 清理标题文本
        link = titleElement.href; // 获取链接
      }

      var authorContainer = row.querySelector('.author');
      var authorTags = Array.from(authorContainer.querySelectorAll('a'));
      var authors = authorTags
      .map(function (authorTag) {
          return authorTag.textContent.trim();
      })
      .filter(function (author) {
          return author !== ''; // 过滤空文本
      });

      var sourceElement = row.querySelector('.source a');
      var source = ''; // 来源默认为空字符串
      if (sourceElement) {
        source = sourceElement.textContent.trim(); // 获取来源文本
      }

      var dateElement = row.querySelector('.date');
      var date = ''; // 日期默认为空字符串
      if (dateElement) {
        date = dateElement.textContent.trim(); // 获取日期文本
      }

      var typeElement = row.querySelector('.data span');
      var type = ''; // 类型默认为空字符串
      if (typeElement) {
        type = typeElement.textContent.trim(); // 获取类型文本
      }

      var rowData = {
        title: title,
        href: link,
        authors: authors,
        source: source,
        date: date,
        type: type
      };

      data.push(rowData);
    }

    console.log(data);
    var htmlContent = document.documentElement.outerHTML;

    var defaultFilename = authorsMatch(htmlContent);
    saveData(JSON.stringify(data, null, 2), defaultFilename);

     // 访问每个链接并保存为单个HTML文件
    data.forEach(function (row, index) {
        var delay = Math.floor(Math.random() * 1000 + 1500); // 随机延迟时间(1500毫秒至2500毫秒)

        setTimeout(function () {
            GM_xmlhttpRequest({
                method: 'GET',
                url: row.href,
                onload: function (response) {
                    //var filename = row.title.replace(/[<>:"\/\\|?*]+/g, '') + '.html';
                    var filename = sanitizeTitle(row.title) + '.html';
                    saveData(response.responseText, filename);
                }
            });
        }, index * delay);
    });

  }
}

// 清理标题以移除非法字符
function sanitizeTitle(title) {
    var invalidChars = /[\/:*?"<>|“ ”]/g;
    return title.replace(invalidChars, '_');
}

// 利用正则表达式匹配第一个作者并作为默认文件名
function authorsMatch(authors) {
  var regex = new RegExp("</i>[^<>:]+:([^<]+)</a>"); // 正则表达式以匹配不同格式的作者标签
  var match = authors.match(regex);
  console.log('match',match[1])
  return match ? match[1] : 'data.'; // 如果匹配成功,返回作者名,否则使用 'data.txt' 作为默认文件名
}




function saveData(data, fileName) {
  var blob = new Blob([data], { type: 'application/json' });
  var reader = new FileReader();
  reader.onloadend = function () {
    var base64data = reader.result;
    var link = document.createElement('a');
    link.href = base64data;
    link.download = fileName + '.json';
    link.click();
  };
  reader.readAsDataURL(blob);
}

// 创建悬浮按钮
var button = document.createElement('div');
button.id = 'getDataButton';
button.style.position = 'fixed';
button.style.bottom = '20px';
button.style.right = '20px';
button.style.width = '50px';
button.style.height = '50px';
button.style.background = '#007bff';
button.style.borderRadius = '50%';
button.style.textAlign = 'center';
button.style.lineHeight = '50px';
button.style.color = '#ffffff';
button.style.cursor = 'pointer';
button.textContent = '获';
button.title = '点击获取页面原始数据';

button.addEventListener('click', function () {
  executeScript = true;
  main();
});

document.body.appendChild(button);

// 检测DOM变化停止后执行脚本
var observer = new MutationObserver(function (mutationsList, observer) {
  for (var mutation of mutationsList) {
    if (mutation.type === 'childList') {
      return;
    }
  }
  observer.disconnect();
  main();
});

observer.observe(document, { childList: true, subtree: true });