cnki-paper-detail について
CNKI の論文詳細ページからメタデータを抽出し、論文情報の整理や確認に使うスキルです。ページスクリプトで取得し、失敗時はアクセシビリティツリーを解析します。
主な機能
- 01タイトルと著者の抽出
- 02所属と抄録の取得
- 03キーワード・助成情報・分類番号の取得
- 04オンライン先行公開の検出
- 05ページ構造による解析への切り替え
活用シーン
- 01CNKI 論文の書誌情報の整理
- 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 が含まれている場合:
- URL を指定して
mcp__chrome-devtools__navigate_pageを使用します。 - テキスト
["摘要"]とタイムアウト 15000 を指定してmcp__chrome-devtools__wait_forを使用します。
2. CAPTCHA を確認する
mcp__chrome-devtools__take_snapshot を使用します。「拖动下方拼图完成验证」が見つかった場合は、ユーザーに次のように知らせます。
CNKI にスライダー CAPTCHA が表示されています。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. フォールバック:スナップショットに基づく解析
JavaScript による抽出に失敗した場合は、mcp__chrome-devtools__take_snapshot を使用し、アクセシビリティツリーを解析します。
- タイトル:レベル 1 の
heading要素 - 著者: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 | CLC 分類コード |
| ジャーナル | .doc-top a | 出典ジャーナルへのリンク |
| オンライン先行公開 | .brief .icon-shoufa | 論文がオンライン先行公開の場合に表示されます |
| 引用タブ | ul.module-tab.tpl_lieteratures li | data-id 属性が種類を識別します |
コメント
Markdown 対応