cnki-export

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

CNKI Export & Zotero Integration

CNKI 导出与 Zotero 集成

Export paper citation data from CNKI and push directly to Zotero, or save as RIS file.
从CNKI导出论文引用数据,直接推送至Zotero,或保存为RIS文件。

Arguments

参数说明

  • zotero
    (default) — push to Zotero desktop via local API
  • ris
    — save as .ris file
  • gb
    — output GB/T 7714 citation text
  • Optionally include a paper URL
  • zotero
    (默认)——通过本地API推送至Zotero桌面端
  • ris
    ——保存为.ris文件
  • gb
    ——输出GB/T 7714格式引用文本
  • 可选传入论文URL

Mode Selection

模式选择

Choose the right mode based on context:
ContextModeTool calls
On a paper detail pageSingle export (Step 1A)1 evaluate + 1 bash = 2
On a search results page, save all/selectedBatch export (Step 1B)1 evaluate + 1 bash = 2
Need to search then saveUse cnki-search first, then batch export4 total
Always prefer batch export (1B) when multiple papers need saving. It avoids navigating to each detail page (saves ~3 calls per paper).
根据使用场景选择合适的模式:
场景模式工具调用次数
在论文详情页单篇导出(步骤1A)1次evaluate + 1次bash = 2次
在搜索结果页,保存全部/选中论文批量导出(步骤1B)1次evaluate + 1次bash = 2次
需要先搜索再保存先使用cnki-search,再进行批量导出共4次
当需要保存多篇论文时,优先选择批量导出(1B)。无需跳转至每篇论文的详情页(每篇论文可减少约3次调用)。

Steps

操作步骤

1A. Single export: from paper detail page

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

Use
mcp__chrome-devtools__evaluate_script
:
javascript
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;
}
调用
mcp__chrome-devtools__evaluate_script
javascript
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. Batch export: from search results page (PREFERRED for multiple papers)

1B. 批量导出:从搜索结果页(多篇论文优先选择)

On any CNKI search results page, extract checkbox values and call the export API directly — no need to navigate to detail pages.
Key discovery:
input.cbItem
checkbox
value
=== detail page
#export-id
(same encrypted ID).
Use
mcp__chrome-devtools__evaluate_script
:
javascript
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
}
To export only specific papers (e.g. #1, #3, #5), filter by index:
javascript
// 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
}
在任意CNKI搜索结果页,提取复选框值并直接调用导出API —— 无需跳转至详情页
关键发现:
input.cbItem
复选框的
value
值 === 详情页的
#export-id
(相同的加密ID)。
调用
mcp__chrome-devtools__evaluate_script
javascript
async () => {
  const API_URL = 'https://kns.cnki.net/dm8/API/GetExport';

  // 获取所有复选框的值(=导出加密ID)
  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;
      // 从ENDNOTE的%@字段提取ISSN
      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数组,可直接写入文件供Python脚本使用
}
仅导出特定论文(例如第1、3、5篇),可通过索引过滤:
javascript
// 替换for循环的条件:
const indices = [0, 2, 4]; // 索引从0开始:对应第1、3、5篇论文
for (let i = 0; i < checkboxes.length; i++) {
  if (!indices.includes(i)) continue;
  // ... 其余代码不变
}

2. Push to Zotero

2. 推送至Zotero

Save the export data (single object or JSON array) to a temp file, then run the Python script:
bash
python "e:/cnki/.claude/skills/cnki-export/scripts/push_to_zotero.py" /tmp/papers.json
The Python script handles both single paper
{}
and batch
[{}, {}, ...]
JSON input.
  • UTF-8 encoding (avoids Windows encoding issues)
  • Parsing ELEARNING format into Zotero item fields
  • Calling
    POST http://127.0.0.1:23119/connector/saveItems
  • Returns: 201 = success, 500 = error, 0 = Zotero not running
将导出数据(单个对象或JSON数组)保存到临时文件,然后运行Python脚本:
bash
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. Report result

3. 结果反馈

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

GB/T 7714 引用: {gbt_citation}
Batch:
已批量添加 {count} 篇论文到 Zotero:
  1. {title1} ({journal1})
  2. {title2} ({journal2})
  ...
单篇导出反馈:
已将论文添加到 Zotero:
  标题: {title}
  作者: {authors}
  期刊: {journal}

GB/T 7714 引用: {gbt_citation}
批量导出反馈:
已批量添加 {count} 篇论文到 Zotero:
  1. {title1} ({journal1})
  2. {title2} ({journal2})
  ...

Export API Reference

导出API参考

ParameterValueSource
API URL
https://kns.cnki.net/dm8/API/GetExport
Fixed, works from any page
filenameEncrypted IDDetail page:
#export-id
; Results page:
input.cbItem
value
displaymode
GBTREFER,elearning,EndNote
Comma-separated modes
uniplatform
NZKPT
Required
参数来源
API URL
https://kns.cnki.net/dm8/API/GetExport
固定值,支持任意页面调用
filename加密ID详情页:
#export-id
;搜索结果页:
input.cbItem
的value值
displaymode
GBTREFER,elearning,EndNote
逗号分隔的模式列表
uniplatform
NZKPT
必填参数

Verified selectors

已验证的选择器

ElementSelectorPage
Export URL
#export-url
Detail page only
Export ID
#export-id
Detail page only
Checkbox (= export ID)
input.cbItem
Search results page
Result rows
.result-table-list tbody tr
Search results page
Title link
td.name a.fz14
Search results page
元素选择器页面
导出URL
#export-url
仅详情页
导出ID
#export-id
仅详情页
复选框(=导出ID)
input.cbItem
搜索结果页
结果行
.result-table-list tbody tr
搜索结果页
标题链接
td.name a.fz14
搜索结果页

Zotero API Reference

Zotero API参考

POST http://127.0.0.1:23119/connector/saveItems
Content-Type: application/json
X-Zotero-Connector-API-Version: 3
Response: 201 = created, 500 = error Collection: Saves to Zotero's currently selected collection.
Query collections:
bash
python "e:/cnki/.claude/skills/cnki-export/scripts/push_to_zotero.py" --list
POST http://127.0.0.1:23119/connector/saveItems
Content-Type: application/json
X-Zotero-Connector-API-Version: 3
响应码: 201 = 创建成功,500 = 错误 保存位置: 保存至Zotero当前选中的集合中。
查询集合列表:
bash
python "e:/cnki/.claude/skills/cnki-export/scripts/push_to_zotero.py" --list

Important Notes

重要注意事项

  • Windows encoding: Must use Python script, cannot pass Chinese JSON via bash/curl directly
  • Zotero must be running:
    localhost:23119
    requires Zotero desktop in background
  • Chinese authors: Use
    name
    field (single field, not split),
    creatorType: "author"
  • Batch export saves ~90% tool calls: 9 papers: 33 calls → 3 calls
  • CNKI Export API:
    filename
    must be encrypted ID (
    #export-id
    or
    input.cbItem
    value), NOT
    #paramfilename
  • Windows编码问题: 必须使用Python脚本,无法直接通过bash/curl传递中文JSON
  • Zotero需处于运行状态:
    localhost:23119
    要求Zotero桌面端在后台运行
  • 中文作者: 使用
    name
    字段(单个字段,不拆分),
    creatorType: "author"
  • 批量导出可节省约90%的工具调用: 9篇论文:33次调用 → 3次调用
  • CNKI导出API:
    filename
    必须为加密ID(
    #export-id
    input.cbItem
    的value值),而非
    #paramfilename