关于 cnki-advanced-search
用于按自然语言条件检索 CNKI 的技能,可组合主题、篇名、作者、来源、年份和来源类别筛选,并读取结果数量。
主要功能
- 01按字段解析检索条件
- 02组合作者、期刊与年份筛选
- 03选择 SCI、EI、CSSCI 等来源类别
- 04获取检索结果数量
适用场景
- 01限定年份和来源类别查找论文
- 02按作者或期刊缩小检索范围
MCP 相关
通过 Chrome DevTools MCP 导航 CNKI,并在页面中填写条件、执行检索和读取结果。
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ cookjohn/ cnki-skills --skill cnki-advanced-search安装后在 Claude Code 中输入/cnki-advanced-search确认已加载。
详细介绍
CNKI 高级检索
使用旧版高级检索界面在 CNKI 上执行筛选检索(这是唯一提供来源类别复选框的界面)。
参数
$ARGUMENTS 用自然语言描述检索条件。解析内容以识别:
- 主题关键词(主题)——默认字段
- 篇名关键词(篇名)
- 关键词(关键词)
- 作者姓名(作者)——独立字段
#au_1_value1 - 期刊/来源(文献来源)——独立字段
#magazine_value1 - 日期范围(时间范围)——
#startYear/#endYear - 来源类别(来源类别:SCI、EI、北大核心、CSSCI、CSCD)
步骤
1. 导航
使用 mcp__chrome-devtools__navigate_page → https://kns.cnki.net/kns/AdvSearch?classid=7NS01R8M
2. 检索并获取结果(单次异步 evaluate_script)
将占位值替换为实际检索条件:
async () => {
// --- Config: fill in actual values ---
const query = "KEYWORDS"; // row 1 search keywords
const fieldType = "SU"; // SU=主题, TI=篇名, KY=关键词, TKA=篇关摘, AB=摘要
const query2 = ""; // row 2 keywords (optional, "" to skip)
const fieldType2 = "KY"; // row 2 field type
const rowLogic = "AND"; // AND=并且, OR=或者, NOT=不含 (between row 1 and 2)
const sourceTypes = ["CSSCI"]; // any of: "SCI", "EI", "hx", "CSSCI", "CSCD" ([] = all)
const startYear = ""; // e.g. "2020" or "" for no limit
const endYear = ""; // e.g. "2025" or "" for no limit
const author = ""; // author name or ""
const journal = ""; // journal name or ""
// --- Wait for form ---
await new Promise((r, j) => {
let n = 0;
const c = () => { if (document.querySelector('#txt_1_value1')) r(); else if (n++ > 30) j('timeout'); else setTimeout(c, 500); };
c();
});
// Captcha check
const cap = document.querySelector('#tcaptcha_transform_dy');
if (cap && cap.getBoundingClientRect().top >= 0) return { error: 'captcha' };
const selects = Array.from(document.querySelectorAll('select')).filter(s => s.offsetParent !== null);
// --- Source type: uncheck 全部, check targets ---
if (sourceTypes.length > 0) {
const gjAll = document.querySelector('#gjAll');
if (gjAll && gjAll.checked) gjAll.click();
for (const st of sourceTypes) {
const cb = document.querySelector('#' + st);
if (cb && !cb.checked) cb.click();
}
}
// --- Row 1: field type + keyword ---
selects[0].value = fieldType;
selects[0].dispatchEvent(new Event('change', { bubbles: true }));
const input = document.querySelector('#txt_1_value1');
input.value = query;
input.dispatchEvent(new Event('input', { bubbles: true }));
// --- Row 2: field type + keyword (optional) ---
if (query2) {
selects[5].value = rowLogic; // row logic: AND/OR/NOT
selects[5].dispatchEvent(new Event('change', { bubbles: true }));
selects[6].value = fieldType2;
selects[6].dispatchEvent(new Event('change', { bubbles: true }));
const input2 = document.querySelector('#txt_2_value1');
input2.value = query2;
input2.dispatchEvent(new Event('input', { bubbles: true }));
}
// --- Author (optional) ---
if (author) {
const auInput = document.querySelector('#au_1_value1');
if (auInput) { auInput.value = author; auInput.dispatchEvent(new Event('input', { bubbles: true })); }
}
// --- Journal (optional) ---
if (journal) {
const magInput = document.querySelector('#magazine_value1');
if (magInput) { magInput.value = journal; magInput.dispatchEvent(new Event('input', { bubbles: true })); }
}
// --- Date range (optional) ---
if (startYear) { selects[14].value = startYear; selects[14].dispatchEvent(new Event('change', { bubbles: true })); }
if (endYear) { selects[15].value = endYear; selects[15].dispatchEvent(new Event('change', { bubbles: true })); }
// --- Submit ---
document.querySelector('div.search')?.click();
// Wait for results
await new Promise((r, j) => {
let n = 0;
const c = () => {
if (document.body.innerText.includes('条结果')) r();
else if (n++ > 40) j('timeout');
else setTimeout(c, 500);
};
setTimeout(c, 2000);
});
// Captcha check again
const cap2 = document.querySelector('#tcaptcha_transform_dy');
if (cap2 && cap2.getBoundingClientRect().top >= 0) return { error: 'captcha' };
return {
query, fieldType, query2, fieldType2, rowLogic,
sourceTypes, startYear, endYear, author, journal,
total: document.querySelector('.pagerTitleCell')?.innerText?.match(/([\d,]+)/)?.[1] || '0',
page: document.querySelector('.countPageMark')?.innerText || '1/1',
url: location.href
};
}
3. 报告
高级检索:“{query}”({fieldType})+ 来源:{sourceTypes} → {total} 条结果。
工具调用:2 次(navigate + evaluate_script)
已验证的选择器(旧版界面)
表单字段
| 元素 | 选择器 / Select 索引 | 说明 |
|---|---|---|
| 第 1 行字段类型 | selects[0] | SU=主题,TI=篇名,KY=关键词,TKA=篇关摘,AB=摘要 |
| 第 1 行关键词 | #txt_1_value1 | 主要关键词输入框 |
| 第 1 行行内第二个词 | #txt_1_value2 | 与第一个关键词使用同一行的 AND/OR/NOT |
| 第 1 行行内逻辑 | selects[2] | AND=并含,OR=或含,NOT=不含 |
| 行间逻辑 | selects[5] | AND=并且,OR=或者,NOT=不含 |
| 第 2 行字段类型 | selects[6] | 与第 1 行选项相同 |
| 第 2 行关键词 | #txt_2_value1 | 第 2 行关键词 |
| 第 2 行行内第二个词 | #txt_2_value2 | |
| 作者 | #au_1_value1 | 占位提示“中文名/英文名/拼音” |
| 作者单位 | #au_1_value2 | 占位提示“全称/简称/曾用名” |
| 文献来源 | #magazine_value1 | 占位提示“期刊名称/ISSN/CN” |
| 基金 | #base_value1 | |
| 起始年份 | selects[14] / #startYear | <select> 1915-2026 |
| 结束年份 | selects[15] / #endYear | <select> 2026-1915 |
| 检索按钮 | div.search | 不是 input/button |
来源类型复选框(来源类型)
| 来源 | 复选框 ID | 说明 |
|---|---|---|
| 全部期刊 | #gjAll | 默认勾选,选择其他选项前需取消勾选 |
| SCI 来源期刊 | #SCI | value="Y" |
| EI 来源期刊 | #EI | value="Y" |
| 北大核心期刊 | #hx | value="Y" |
| CSSCI | #CSSCI | value="Y" |
| CSCD | #CSCD | value="Y" |
可同时勾选多个来源类型(OR 逻辑)。
结果
| 元素 | 选择器 | 说明 |
|---|---|---|
| 结果数 | .pagerTitleCell | 文本“共找到 X 条结果” |
| 页码指示器 | .countPageMark | 文本“1/300” |
验证码检测
检查 #tcaptcha_transform_dy 元素的 getBoundingClientRect().top >= 0。
重要说明
- 必须使用旧版 URL(
kns.cnki.net/kns/AdvSearch)。新版界面(kns8s/AdvSearch)没有来源类别复选框。 classid=7NS01R8M参数可确保加载正确的表单布局。- 结果页兼容
cnki-parse-results和cnki-navigate-pages技能。
评论
支持 Markdown