关于 cnki-paper-detail
从 CNKI 论文详情页提取完整元数据的技能,适用于整理和查看论文信息。支持页面脚本提取,并可在失败时依据无障碍页面结构解析。
主要功能
- 01提取标题与作者
- 02获取作者单位和摘要
- 03读取关键词、基金与分类号
- 04识别网络首发状态
- 05支持页面结构解析回退
适用场景
- 01整理 CNKI 论文的书目信息
- 02从详情页收集摘要和关键词
- 03验证码通过后继续读取论文信息
MCP 相关
使用 Chrome DevTools MCP 导航论文页面、检测验证码,并执行页面脚本或读取页面快照。
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ cookjohn/ cnki-skills --skill cnki-paper-detail安装后在 Claude Code 中输入/cnki-paper-detail确认已加载。
详细介绍
CNKI 论文详情提取
从 CNKI 论文详情页提取完整元数据。
参数
$ARGUMENTS 是可选的 CNKI 论文详情页 URL(包含 kcms2/article/abstract)。如果未提供,则假定当前页面已经是论文详情页。
步骤
1. 导航至论文页面(如果提供了 URL)
如果 $ARGUMENTS 包含 URL:
- 使用
mcp__chrome-devtools__navigate_page并传入该 URL。 - 使用
mcp__chrome-devtools__wait_for,文本设为["摘要"],超时时间设为 15000。
2. 检查验证码
使用 mcp__chrome-devtools__take_snapshot。如果发现“拖动下方拼图完成验证”,请通知用户:
CNKI 正在显示滑块验证码。请在 Chrome 浏览器中手动完成拼图验证,完成后告诉我继续。
3. 通过 JavaScript 提取论文元数据
使用 mcp__chrome-devtools__evaluate_script 并传入此函数:
() => {
const brief = document.querySelector('.brief');
if (!brief) return { error: 'Paper detail section (.brief) not found' };
// Title
const title = brief.querySelector('h1')?.innerText?.trim()
?.replace(/\s*附视频\s*$/, '') // remove "附视频" suffix
?.replace(/\s*网络首发\s*$/, ''); // remove "网络首发" suffix
// Authors - first h3.author contains author links with sup tags
const authorH3s = brief.querySelectorAll('h3.author');
const authorSection = authorH3s[0];
const authors = [];
if (authorSection) {
const authorLinks = authorSection.querySelectorAll('a');
authorLinks.forEach(a => {
const name = a.innerText?.replace(/\d+$/, '').trim();
const supMatch = a.innerText?.match(/(\d+)$/);
const affiliationNum = supMatch ? supMatch[1] : '';
authors.push({ name, affiliationNum });
});
}
// Affiliations - second h3.author contains org links
const affiliations = [];
if (authorH3s.length > 1) {
const orgLinks = authorH3s[1].querySelectorAll('a');
orgLinks.forEach(a => {
affiliations.push(a.innerText?.trim());
});
}
// Abstract
const abstractEl = document.querySelector('.abstract-text');
const abstract = abstractEl?.innerText?.trim() || '';
// Keywords
const keywordsP = document.querySelector('p.keywords');
const keywords = keywordsP
? Array.from(keywordsP.querySelectorAll('a')).map(a => a.innerText?.replace(/;$/, '').trim())
: [];
// Fund
const fundsP = document.querySelector('p.funds');
const fund = fundsP?.innerText?.trim() || '';
// Classification code
const clcCode = document.querySelector('.clc-code');
const classification = clcCode?.innerText?.trim() || '';
// Journal/source
const docTop = document.querySelector('.doc-top');
const journal = docTop?.querySelector('a')?.innerText?.trim() || '';
// Online first / publication info
const headTime = document.querySelector('.head-time');
const pubInfo = headTime?.innerText?.trim() || '';
// Is online first?
const isOnlineFirst = !!brief.querySelector('.icon-shoufa');
// Article outline/TOC
const catalogList = document.querySelector('.catalog-list, .catalog-listDiv');
const toc = catalogList?.innerText?.trim() || '';
// Citation network counts
const citationTabs = document.querySelectorAll('ul.module-tab.tpl_lieteratures li');
const citationInfo = {};
citationTabs.forEach(li => {
const id = li.getAttribute('data-id');
const text = li.innerText?.trim();
const countMatch = text.match(/(\d+)/);
if (id) {
citationInfo[id] = {
label: text.replace(/\d+/, '').trim(),
count: countMatch ? parseInt(countMatch[1]) : 0
};
}
});
return {
title,
authors,
affiliations,
abstract,
keywords,
fund,
classification,
journal,
pubInfo,
isOnlineFirst,
toc,
citationInfo
};
}
4. 格式化并展示输出
## {title} {isOnlineFirst ? "[网络首发]" : ""}
**Authors:**
{For each author: "- {name} ({affiliation})"}
**Affiliations:**
{For each affiliation: "- {affiliation}"}
**Journal:** {journal}
**Publication Info:** {pubInfo}
**Abstract:**
{abstract}
**Keywords:** {keywords joined by ", "}
**Fund:** {fund}
**Classification:** {classification}
**Citation Network:**
{For each citation type: "- {label}: {count}"}
5. 回退方案:基于快照解析
如果 JS 提取失败,则使用 mcp__chrome-devtools__take_snapshot 并解析无障碍树:
- 标题:
heading的 1 级元素 - 作者:URL 包含
kcms2/author/detail的link元素 - 机构:URL 包含
kcms2/organ/detail的link元素 - 摘要:"摘要:"后面的
StaticText - 关键词:URL 包含
kcms2/keyword/detail的link元素 - 基金:"基金资助:"后面的
link元素 - 分类号:"分类号:"后面的
StaticText
已验证的 DOM 选择器
| 数据 | 选择器 | 说明 |
|---|---|---|
| 论文区域 | .brief | 论文主要信息容器 |
| 标题 | .brief h1 | 可能包含图标,需要提取纯文本 |
| 作者 | .brief h3.author:first-of-type a | 文本带有上标数字(例如,“张三1”) |
| 机构 | .brief h3.author:nth-of-type(2) a | 文本以“N.”开头(例如,“1.北京大学”) |
| 摘要 | .abstract-text | 完整摘要文本 |
| 关键词 | p.keywords a | 以分号分隔的关键词链接 |
| 基金 | p.funds | 基金信息文本 |
| 分类号 | .clc-code | 中图分类号代码 |
| 期刊 | .doc-top a | 来源期刊链接 |
| 网络首发 | .brief .icon-shoufa | 论文为网络首发时显示 |
| 引文选项卡 | ul.module-tab.tpl_lieteratures li | data-id 属性用于标识类型 |
评论
支持 Markdown