mcpField
F
fulltext-retrieval

fulltext-retrieval

github.com/aperivue文档处理353123 次安装1 天前更新
代码仓库

关于 fulltext-retrieval

fulltext-retrieval 是通过 DOI 列表批量获取开放获取论文 PDF 的命令行技能,适合整理文献的研究者。它按顺序尝试指定的合法来源,并将未能获取的论文列出,供机构访问或馆际互借。

主要功能

  1. 01根据 DOI 列表获取 PDF
  2. 02依次查询 arXiv、Unpaywall、PMC 等来源
  3. 03记录获取结果与身份核验依据
  4. 04列出需要手动访问的论文
  5. 05可选将 PDF 转为 Markdown

适用场景

  1. 01为文献综述收集开放获取论文
  2. 02为荟萃分析获取 PDF
  3. 03将需反复阅读的论文转换为 Markdown

安装

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

$npx skills add https://github.com/aperivue/medsci-skills --skill fulltext-retrieval

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

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

fetch_oa.py
pdf_to_md.py
skill.yml
fetch_oa_report_challenge/
extracted_text.json
results.json
run_challenge.py
verify.sh
worklist.tsv
fetch_oa_report_challenge/expected/
projection.json
references/
find_available_pdf.js
tests/
test_pdf_to_md.py
test_source_identity.py

详细介绍

全文检索技能

仅使用合法的 OA API,根据 DOI 列表批量下载开放获取的全文 PDF。 付费墙文章会按设计无法下载,并列入 manual_needed.txt,供通过机构访问或馆际互借获取; 切勿绕过付费墙或出版商的访问控制。

流程

DOI → arXiv (10.48550/arXiv.* DOIs) → Unpaywall → PMC (Europe PMC / OA FTP / web) → OpenAlex → Crossref → landing page

每个 DOI 都会依次通过这些来源查找,直到找到有效的 PDF(≥10 KB,且具有 %PDF- 文件头)。 arXiv DOI(10.48550/arXiv.2401.01234、带版本后缀的 DOI、旧格式 hep-th/9901001 或不带前缀的 arXiv: ID)会优先直接解析为 arXiv PDF。

运行

需要 Python 3.10+(仅使用标准库)和联系邮箱,这是 Unpaywall 服务条款所要求的。 脚本会控制请求频率(间隔 0.3–0.5 秒),以符合各 API 的速率限制。

python "${CLAUDE_SKILL_DIR}/fetch_oa.py" dois.txt --output pdfs/ --email [email protected]

# Verbose mode for debugging (per-DOI source trace)
python "${CLAUDE_SKILL_DIR}/fetch_oa.py" dois.txt -o pdfs/ -e [email protected] --verbose

输入格式:

  • 纯文本 —— 每行一个 DOI。
  • 带表头的 TSV / CSV 或 Markdown 竖线表格 —— 必须包含 DOI 列;可选列包括 PMID、Title 和 FirstAuthor(姓氏或全名)。

提供 PMID 可提高 PMC 查询的可靠性(通过 PMID → PMCID 转换)。请尽可能提供 Title:仅包含 DOI 的工作列表可以下载 PDF,但无法确认标题是否一致。 FirstAuthor 可选,可作为补充依据。

输出

  • PDF 保存为 {DOI_safe}.pdf(斜杠会替换为下划线)。
  • pdfs/retrieval_report.json —— 按 DOI 组织的结构化报告(见下文);可用 --report PATH 覆盖。
  • <output>/manual_needed.txt —— 无法通过 OA 获取的 DOI;若已解析出 PMCID,该行还会附带 PMCID 和 PubMed Central 文章网址,供在浏览器中打开。
  • 摘要包含 arXiv/OA/PMC/失败/跳过的数量。

检索报告(--report)

每次运行都会写入报告(默认路径为 <output>/retrieval_report.json),使用 schema 2:

{
  "schema_version": 2,
  "generated_by": "fetch_oa.py",
  "counts": {"total": 4, "retrieved": 3, "not_retrieved": 1, "title_mismatch": 1,
             "source_identity": {"consistent": 1, "conflict": 1, "unresolved": 1, "unavailable": 1}},
  "items": [
    {"doi": "10.1000/synthetic.example", "pmid": "", "title": "Example title",
     "first_author": "", "status": "oa", "source": "unpaywall",
     "file": "10.1000_synthetic.example.pdf", "size_bytes": 482113, "page_count": 9,
     "file_sha256": "<SHA-256 of the downloaded file>", "title_match": "match",
     "source_identity": {"status": "consistent", "reason": "title_and_identifier_agree",
                         "text_scope": "first_page_front_matter", "title_match": "match",
                         "doi_match": "match", "observed_identifiers": ["10.1000/synthetic.example"],
                         "first_author_match": "unavailable"}}
  ]
}

status(arxiv | oa | pmc | skip | fail)、source 和 counts.retrieved 描述解析器的结果,包括已存在的文件(skip)。**它们不统计身份已验证的论文。**不会自动删除或拒收任何 PDF。page_count 来自 Poppler 的 pdfinfo(没有时为 null),只作记录、不作判定——3 页的“文章”或 4 页的“书”都值得打开查看。

source_identity.status含义 / 操作
consistent首页限定范围内的前置内容中,出现完整的规范化标题和兼容的 DOI/arXiv 标识符,且没有补充材料 / 序言 / 目录标题,也没有撤稿 / 勘误 / 更正 / 更正声明 / 关注声明标题;若提供了作者,也必须匹配。证据相符,但这不代表进行了独立来源验证或主张核验。
conflict标题和检测到的标识符均不匹配。请检查 PDF 和请求记录。
unresolved证据不完整或含糊:只有标题、只有 DOI、缺少作者、存在多个标识符、标题匹配但 DOI/版本不同,或补充材料 / 序言 / 目录文件提及了该作品,但文件本身并非该作品(supplement_or_front_matter)。位于该区域内标题行中的撤稿通知、勘误、更正、更正声明或关注声明同样标记为 unresolved(correction_or_retraction_notice)。将其用作证据前请先检查。
unavailable没有可用的提取文本、Poppler 不可用、没有输出 PDF,或评估期间 PDF 发生变化。无法进行当前身份评估。

证据仅限首页中、可识别的摘要 / 正文 / 参考文献标题之前的内容(最多 40 行 / 4,000 个字符),因此正文或参考文献中引用的标题不计入。title_match 为 match 时,完整的规范化标题必须出现在最多 6 行连续文本中;部分重合标记为 unavailable,重合度低则标记为提示性 mismatch。封面页、异常的阅读顺序、较短或经过更改的标题,以及该范围之外的 DOI 页脚,都可能导致状态保持为 unresolved。PDF 元数据和文件名本身不是身份依据。明确指定的 arXiv 版本必须一致;预印本与已发表版本的 DOI 不同,需要审核,而不是自动拒收。

下游报告必须保留 source_identity 和 file_sha256,让 unresolved 项目保持可见,并检查哈希是否仍对应正在使用的文件。较早且没有身份证据的报告仍属于未评估;不要根据 retrieved 或 title_match=match 推断身份。全文转换无法消除身份警告。

将 PDF 附加到 Zotero(“查找可用的 PDF”)

对于 OA 解析器未能找到、但用户有权访问的付费墙后论文,references/find_available_pdf.js 是一段由用户运行的代码片段,可在 Zotero 的 工具 → 开发者 → 运行 JavaScript 中执行(无代码方式:右键 →“查找可用的 PDF”)。它会触发 Zotero 自带的 addAvailablePDF / addAvailablePDFs,因此会复用用户自己的 OpenURL 解析器 / 机构代理配置;不会将凭据、代理主机或机构标识符写入硬编码内容,也不会将其带出 Zotero 客户端。此操作由用户发起,并依赖当前运行中的 Zotero 会话,因此请手动记录结果——它们不是可复现的 CI 证据。/lit-sync 的 Phase 2.7 会协调这两种方式并在报告中进行核对。

PDF → Markdown 转换(可选)

当同一批论文需要反复阅读时(从 k≥5 项研究中提取数据、运行荟萃分析工作流),可将下载的 PDF 转换为 Markdown;对于只需阅读一次的筛选,直接阅读 PDF 即可。

# Install (one-time)
pip install pymupdf4llm

# Convert all PDFs in a directory (.md files land alongside the .pdf files)
python "${CLAUDE_SKILL_DIR}/pdf_to_md.py" pdfs/ -v

# Custom output directory
python "${CLAUDE_SKILL_DIR}/pdf_to_md.py" pdfs/ -o markdown/

# First 10 pages only (useful for long supplements)
python "${CLAUDE_SKILL_DIR}/pdf_to_md.py" pdfs/ --pages 0-9

# Overwrite existing conversions
python "${CLAUDE_SKILL_DIR}/pdf_to_md.py" pdfs/ --force

转换会跳过图片,因此图表只会以图注文本的形式保留。仅扫描版 PDF(没有文本层)的转换效果较差。pdf_to_md.py 需要 pymupdf4llm(AGPL-3.0),这是一个可选依赖项;fetch_oa.py 仅使用标准库。

评论

支持 Markdown