mcpField
C
cnki-export

cnki-export

github.com/cookjohn生产力1.0k414 次安装33 周前更新
代码仓库

关于 cnki-export

用于导出 CNKI 论文引文数据并保存到 Zotero 或 RIS 文件,也可生成 GB/T 7714 引文文本。适合整理单篇或搜索结果中的多篇论文。

主要功能

  1. 01导出单篇或批量论文数据
  2. 02推送条目到 Zotero
  3. 03保存为 RIS 文件
  4. 04生成 GB/T 7714 引文

适用场景

  1. 01将 CNKI 搜索结果批量加入 Zotero
  2. 02从论文详情页保存引文条目
  3. 03为论文整理 RIS 或 GB/T 7714 格式

MCP 相关

此技能使用 Chrome DevTools MCP 从 CNKI 页面提取导出数据,并通过本地脚本与 Zotero 桌面端连接;README 未说明该脚本通过 MCP 暴露服务。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/cookjohn/cnki-skills --skill cnki-export

安装后在 Claude Code 中输入/cnki-export确认已加载。

附带文件scripts/push_to_zotero.py

详细介绍

CNKI 导出与 Zotero 集成

从 CNKI 导出论文引文数据并直接推送到 Zotero,或保存为 RIS 文件。

参数

  • zotero(默认)— 通过本地 API 推送到 Zotero 桌面端
  • ris — 保存为 .ris 文件
  • gb — 输出 GB/T 7714 引文文本
  • 可选地包含论文 URL

模式选择

根据上下文选择合适的模式:

上下文模式工具调用
在论文详情页上单篇导出(步骤 1A)1 次 evaluate + 1 次 bash = 2
在搜索结果页上,保存全部/选中的论文批量导出(步骤 1B)1 次 evaluate + 1 次 bash = 2
需要先搜索再保存先使用 cnki-search,再批量导出共 4 次

需要保存多篇论文时,始终优先使用批量导出(1B)。 这样无需导航到每个详情页(每篇论文可节省约 3 次调用)。

步骤

1A. 单篇导出:从论文详情页导出

使用 mcp__chrome-devtools__evaluate_script:

async () => {
  const url = document.querySelector('#export-url')?.value;
  const params = document.querySelector('#export-id')?.value;
  const uniplatform = new URLSearchParams(window.location.search).get('uniplatform') || 'NZKPT';
  if (!url || !params) return { error: 'Not on a paper detail page' };

  const resp = await fetch(url, {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({ filename: params, displaymode: 'GBTREFER,elearning,EndNote', uniplatform })
  });
  const data = await resp.json();
  if (data.code !== 1) return { error: data.msg };

  const result = {};
  for (const item of data.data) {
    result[item.mode] = item.value[0];
  }

  const body = document.body.innerText;
  result.pageUrl = window.location.href;
  result.issn = body.match(/ISSN[::]\s*(\S+)/)?.[1] || '';
  result.dbcode = document.querySelector('#paramdbcode')?.value || '';
  result.dbname = document.querySelector('#paramdbname')?.value || '';
  result.filename = document.querySelector('#paramfilename')?.value || '';

  return result;
}
1B. 批量导出:从搜索结果页导出(多篇论文时优先使用)

在任何 CNKI 搜索结果页上,提取复选框的值并直接调用导出 API——无需导航到详情页。

关键发现:input.cbItem 复选框的 value === 详情页的 #export-id(同一个加密 ID)。

使用 mcp__chrome-devtools__evaluate_script:

async () => {
  const API_URL = 'https://kns.cnki.net/dm8/API/GetExport';

  // Get all checkbox values (= export encrypted IDs)
  const checkboxes = document.querySelectorAll('.result-table-list tbody input.cbItem');
  const rows = document.querySelectorAll('.result-table-list tbody tr');

  if (checkboxes.length === 0) return { error: 'No results on page' };

  const allPapers = [];
  for (let i = 0; i < checkboxes.length; i++) {
    const exportId = checkboxes[i].value;
    const paperUrl = rows[i]?.querySelector('td.name a.fz14')?.href || '';

    const resp = await fetch(API_URL, {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: new URLSearchParams({ filename: exportId, displaymode: 'GBTREFER,elearning,EndNote', uniplatform: 'NZKPT' })
    });
    const data = await resp.json();
    if (data.code === 1) {
      const result = {};
      for (const item of data.data) { result[item.mode] = item.value[0]; }
      result.pageUrl = paperUrl;
      // Extract ISSN from ENDNOTE %@ field
      const issnMatch = result.ENDNOTE?.match(/%@\s*([^\s<]+)/);
      result.issn = issnMatch ? issnMatch[1] : '';
      result.dbcode = 'CJFQ';
      result.dbname = '';
      result.filename = '';
      allPapers.push(result);
    }
  }

  return allPapers; // JSON array, directly writable to file for Python script
}

若只导出特定论文(例如第 1、3、5 篇),请按索引筛选:

// Replace the for loop condition:
const indices = [0, 2, 4]; // 0-indexed: papers #1, #3, #5
for (let i = 0; i < checkboxes.length; i++) {
  if (!indices.includes(i)) continue;
  // ... rest same
}
2. 推送到 Zotero

将导出数据(单个对象或 JSON 数组)保存到临时文件,然后运行 Python 脚本:

python "e:/cnki/.claude/skills/cnki-export/scripts/push_to_zotero.py" /tmp/papers.json

Python 脚本支持单篇论文 {} 和批量 [{}, {}, ...] JSON 输入。

  • 使用 UTF-8 编码(避免 Windows 编码问题)
  • 将 ELEARNING 格式解析为 Zotero 条目字段
  • 调用 POST http://127.0.0.1:23119/connector/saveItems
  • 返回值:201 = 成功,500 = 出错,0 = Zotero 未运行
3. 报告结果

单篇:

已将论文添加到 Zotero:
  标题: {title}
  作者: {authors}
  期刊: {journal}

GB/T 7714 引用: {gbt_citation}

批量:

已批量添加 {count} 篇论文到 Zotero:
  1. {title1} ({journal1})
  2. {title2} ({journal2})
  ...

导出 API 参考

参数值来源
API URLhttps://kns.cnki.net/dm8/API/GetExport固定值,可从任何页面使用
filename加密 ID详情页:#export-id;结果页:input.cbItem 的值
displaymodeGBTREFER,elearning,EndNote逗号分隔的模式
uniplatformNZKPT必填

已验证的选择器

元素选择器页面
导出 URL#export-url仅详情页
导出 ID#export-id仅详情页
复选框(= 导出 ID)input.cbItem搜索结果页
结果行.result-table-list tbody tr搜索结果页
标题链接td.name a.fz14搜索结果页

Zotero API 参考

POST http://127.0.0.1:23119/connector/saveItems
Content-Type: application/json
X-Zotero-Connector-API-Version: 3

响应: 201 = 已创建,500 = 出错 收藏集: 保存到 Zotero 当前选中的收藏集。

查询收藏集:

python "e:/cnki/.claude/skills/cnki-export/scripts/push_to_zotero.py" --list

重要说明

  • Windows 编码: 必须使用 Python 脚本,不能通过 bash/curl 直接传递中文 JSON
  • Zotero 必须正在运行: localhost:23119 要求 Zotero 桌面端在后台运行
  • 中文作者: 使用 name 字段(单个字段,不拆分),creatorType: "author"
  • 批量导出可节省约 90% 的工具调用: 9 篇论文:33 次调用 → 3 次调用
  • CNKI 导出 API: filename 必须是加密 ID(#export-id 或 input.cbItem 的值),不能是 #paramfilename

评论

支持 Markdown