Community研究&データ分析github.com

GreenWich-art/agent-skills

PMCからオープンアクセスの生物医学論文PDFをダウンロードし、オフラインでProof-of-Workを解決します。トリガー: 下载文献PDF, PMC PDF, 403/404 on PDF link, Preparing to download, reCAPTCHA page, OA full text, supplementary files, download paper PDF.

agent-skills とは?

このスキルは、AIエージェント(Claude Code、Cursor、Codexなど)がPMC(PubMed Central)からオープンアクセス(OA)の生物医学論文PDFを効率的に取得するためのツールです。PMCのPDF配信にはProof-of-Work(PoW)チャレンジが実装されており、reCAPTCHAに遭遇することなくオフラインでPoWを解決してPDFをダウンロードする手法を提供します。主な機能は、`scripts/pmc_pdf.py`スクリプトによる自動PDFファイル名解決とPoW解決です。このスキルは、機関購読環境下での適切な利用(単一論文の手動ダウンロード、バルクダウンロード禁止)と、出版社直リンクや補足資料へのフォールバック戦略もカバーします。また、PMCのreCAPTCHAやIP制限が発生した場合の回避策(出版社公式サイト経由、ブラウザの「PDFに印刷」機能)も提供します。ダウンロード後は、ファイルヘッダ、フッタ、ページ数による完全性チェックを実施します。ターゲットプラットフォームは、Linux、macOS、Windowsで動作するPythonベースの環境です。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/GreenWich-art/agent-skills/tree/HEAD/skills/pmc-oa-pdf-fetch

Installed? Explore more 研究&データ分析 skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

PMC / OA 文献 PDF 取得

適用前提

開放アクセス(OA) 文献(CC BY / CC BY-NC / CC BY-NC-ND など)のみに使用すること。有料購読論文のペイウォール回避目的での使用は禁止——これは著作権保護の迂回に該当する。OA状態の判定:Unpaywall が is_oa: true を返す、または EuropePMC の isOpenAccess: Y を確認。

機関購読シナリオ(重要な補足)

ユーザーの所属大学・研究機関が出版社データベースを購読している場合、手動での単一論文ダウンロードは認可範囲内で完全に合法だが、以下の点に注意:

  • キャンパスネットワーク / 機関IP範囲内:出版社はIPアドレスを認証に使用するため、フォールバックチェーンの第5段階(出版社直リンク)は通常200を返し、Cloudflareによるブロックも発生しない。この場合、本スキルの既存パイプラインは購読コンテンツを直接取得可能で、ログイン処理は不要。
  • 外部アクセス:可能な限り所属機関が提供するシステムレベルVPN(スクリプトに対して透過的で、一度設定すればOK)を優先使用すること。WebVPN(URL書き換え型プロキシ)は機関ごとの書き換えルールが異なり、セッションCookieが必要なため、本スキルではサポートしない。
  • Shibboleth / OpenAthens の自動ログインは記述しないこと:統一認証情報をローカルに保存する必要があり、セキュリティリスクとなる。また各機関のIdPフローは多様で、汎用的な実装は不可能。
  • バルクダウンロードの禁止:ほぼすべての出版社の機関ライセンスは、「手動での単一論文ダウンロード」と「組織的/バルクダウンロード」を区別している。購読がある場合でも、スクリプトによるバッチ取得はライセンス違反となり、所属機関の全IPがブロックされる可能性がある。大規模な全文テキストマイニングが必要な場合は、出版社のTDM(テキストマイニング)API(例:Elsevier TDM API、Springer Nature Meta API)を申請し、公式のクォータルートを利用すること。本スキルをバッチループに使用しないこと。

フォールバックチェーン(厳密な順序で)

優先度経路コマンド / エンドポイント説明
1EuropePMC 構造化全文https://www.ebi.ac.uk/europepmc/webservices/rest/{PMCID}/fullTextXML最も安定。セクション見出しレベルまで正確な全文構造を抽出するために使用。JATS XMLを返す。
2Unpaywall によるOA場所の特定https://api.unpaywall.org/v2/{DOI}[email protected]oa_locations[].url_for_pdf を読み、PDF直リンクを直接取得。
3PMC PoW 解決ダウンロードscripts/pmc_pdf.py <PMCID> <out.pdf>下記参照。本文PDF取得の主力手法。
4EuropePMC 補足資料https://www.ebi.ac.uk/europepmc/webservices/rest/{PMCID}/supplementaryFilesZIPを返す:元画像(gr1… = Figure 1…)+ 補足資料PDF(mmc1.pdf)。
5出版社直リンク各出版社 .../article-pdf/...通常403(Cloudflare)。最後の手段として試すこと。

動作確認済みの無効なエンドポイント(時間を無駄にしないこと)

  • …/rest/{PMCID}/fullTextPDF → 404(廃止)
  • …/rest/{PMCID}/fulltextRepo → 403
  • https://europepmc.org/articles/{PMCID}?pdf=render → 403
  • https://europepmc.org/backend/ptpmcrender.fcgi?accid=…&blobtype=pdf → 403
  • https://www.ncbi.nlm.nih.gov/pmc/utils/oa/oa.fcgi?id=… → 404(OAサービス移転)
  • ashpublications.org の記事ページは、ヘッドレスブラウザで Cloudflare の「お待ちください…」チャレンジ画面で停止するため使用不可

★ 前提条件:PMC の PDF ファイル名は固定ではないため、事前に解決する必要がある

https://pmc.ncbi.nlm.nih.gov/articles/{PMCID}/pdf/<ファイル名>.pdf の <ファイル名> はジャーナルと発行年によって変化する。main.pdf とハードコードすると、多くの場合404が返る。

実測ジャーナル実際のファイル名
Am J Hematolmain.pdf
Blood Advancesmain.pdf
HemaSphereHEM3-10-e70338.pdf
Am J HematolAJH-101-1790.pdf
Liver InternationalLIV-46-0.pdf
Haematologica111300.pdf(巻111 + 開始ページ300、ジャーナル略称なし)
Blood(NIH著者原稿)nihms-2192199.pdf

解析方法(優先順位順;実測の複数例で全て1番目にヒット)

  1. 記事ページの <meta name="citation_pdf_url" content="https://pmc.ncbi.nlm.nih.gov/articles/{PMCID}/pdf/XXX.pdf"> ← 最も信頼性が高い
  2. grep -oE 'href="[^"]*?/pdf/[^"]+?\.pdf"' で最初のヒットを取得
  3. フォールバック:pdf/main.pdf

命名規則の参考(信頼はしないこと。解析が正しいかどうかの手動確認のみに使用):Wiley系OAでは <ジャーナル略称>-<印刷巻>-0.pdf(例 LIV-46-0.pdf)が一般的。採番記事の場合は <ジャーナル略称>-<巻>-<記事番号>.pdf(例 HEM3-10-e70338.pdf)。同じジャーナル内では <略称>-<巻>-<開始ページ>.pdf(例 AJH-101-1790.pdf)が多い。また「巻+開始ページでジャーナル略称なし」のバリエーションもある(Haematologica の 111300.pdf = 巻111 + 開始ページ300)。

記事ページ取得時は必ずCookieを破棄すること:独立した、Cookieを保持しないリクエストで記事ページを読み、PDFリクエストは新しいCookieセッションから開始する必要がある。記事ページで生成された ncbi_sid / ncbi_pinger をPDFリクエストに持ち越すと、直接reCAPTCHAに昇格される(実測)。scripts/pmc_pdf.py はこの実装になっている。

核心的手法:PMC Proof-of-Workのオフライン解決

原理

https://pmc.ncbi.nlm.nih.gov/articles/{PMCID}/pdf/<ファイル名>.pdf は、リスクポリシーに基づいて2種類のチャレンジページを切り替える:

  • PoWページ(1817バイト、タイトル Preparing to download ...)→ オフラインで解決可能。これが目的のチャネル。
  • reCAPTCHAページ(約20KB、タイトルに reCAPTCHA を含む)→ オフラインでは解決不可。

PoWをトリガーしreCAPTCHAを回避する鍵:シンプルなUser-Agentを使用し、PDFをリクエストする前に記事ページにアクセスしないこと。

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)

逆効果(reCAPTCHAに昇格される、実測):

  • 完全なChrome UA(…AppleWebKit/537.36 … Chrome/1xx.0.0.0 Safari/537.36)
  • 先に GET で記事ページにアクセス(ncbi_sid / ncbi_pinger を保持)してからPDFをリクエスト

PoW アルゴリズム(pow-*.js からリバースエンジニアリング済み、確認済み)

PoWページには4つの定数が埋め込まれている:POW_CHALLENGE / POW_DIFFICULTY / POW_COOKIE_NAME / POW_COOKIE_PATH。

  1. 最小の非負整数 nonce を求め、sha256(challenge + str(nonce)).hexdigest() の先頭が '0' * difficulty と一致すること。
  2. Cookieを設定:<POW_COOKIE_NAME> = challenge + "," + nonce(パスは POW_COOKIE_PATH)。
  3. そのCookieと Referer: https://pmc.ncbi.nlm.nih.gov/articles/{PMCID}/ を付けてPDF直リンクに再リクエスト → 200 と Content-Type: application/pdf が返るはず。

典型的な difficulty = 4(期待されるハッシュ数は約65536回、ローカルではサブ秒で完了)。

ワンクリックスクリプト

# 推奨:実際のPDFファイル名を自動解析(citation_pdf_url経由)、その後PoWをオフライン解決
python3 scripts/pmc_pdf.py PMC13575452 ./out.pdf

# 自分でファイル名を解析済みの場合、直接指定して記事ページリクエストをスキップ
python3 scripts/pmc_pdf.py PMC13575452 ./out.pdf --pdf-name LIV-46-0.pdf

# サイレントモード(結果行のみ出力)
python3 scripts/pmc_pdf.py PMC13575452 ./out.pdf --quiet

スクリプトの動作:まずシンプルなUAで、Cookieを破棄して記事ページにアクセスし、実際のPDF直リンクを解析 → 次に新しいCookieセッションでそのPDFにコールドリクエスト → 直接PDFが得られれば保存、そうでなければPoW定数を解析、解決、Cookieを埋め戻して再試行。チャレンジを強制的に再取得したい場合は再実行する(スクリプトはCookieをディスクに保存せず、毎回新しいセッションになる)。

★★ 絶対に覚えておくべき2つの厳格なルール(実測による血の教訓)

1. 2番目の位置引数は出力ファイルのフルパスであり、ディレクトリではない。 ディレクトリを渡すと、PDFを取得した後に IsADirectoryError: [Errno 21] Is a directory がスローされ、それまでのPoW解決は無駄になり、取得したPDFも失われる。 ❌ pmc_pdf.py PMC13482240 --outdir /path/to/dir  ✅ pmc_pdf.py PMC13482240 /path/to/dir/xxx.pdf

2. PMCのPDFチャネルには「一度きり」の特性がある。 初回のコールドリクエストはほぼ確実にPoWを通過し、実際のPDFを取得できる。その後、同じPDFに対して再度リクエストすると、ほぼ確実にreCAPTCHAに昇格される(「UAを変えればOK」という通常のレート制限とは異なる)。 したがって最初から出力パスを正しく指定し、決して「試しに実行してみる」ことをしてはならない。 実測:初回 status=200 type=application/pdf bytes=23970819、数秒後に同じURLを再実行すると type=text/html bytes=21329(reCAPTCHAチャレンジページ)に変化。 一度この機会を無駄にすると、次のセクションの「出版社公式サイトへのフォールバックルート」に直接進むこと。PMCで繰り返しリトライしてはならない。

トラブルシューティング

現象原因対応
HTMLが返り、POW_CHALLENGE を含むPoWチャネルに入った(正常)スクリプトで解決
HTMLが返り、recaptcha を含むreCAPTCHAに昇格されたシンプルなUAに変更、セッションCookieをクリア、少し待ってから再試行。それでも失敗する場合は経路4/5を使用
404 / 「Article not found」PDFファイル名が間違っている記事ページに戻って citation_pdf_url を解析すること。main.pdf をハードコードしないこと
nonce がなかなか収束しないdifficulty が引き上げられたdifficulty を表示して判断。>5の場合は非同期またはマルチプロセスでの解決を検討
解決成功したがPDFがHTMLのままCookieのドメイン/パスが一致しないCookieのドメインが pmc.ncbi.nlm.nih.gov、パスが POW_COOKIE_PATH であることを確認
IsADirectoryError: Is a directory出力引数をディレクトリとして扱っている第2引数は出力ファイルのフルパス。 このエラーが出るときは、実はPDFは取得できているが、ディスクに書き込まれていない——すぐに再実行しないこと(reCAPTCHAを誘発する)。まずパスを修正し、すでに昇格している場合は出版社公式サイトルートに進む。
初回成功、2回目で即reCAPTCHAPMCが同一PDFパスに対して「一度きり」のレート制限をかけている上記の厳格ルール2を参照。PMCを諦め、出版社公式サイトへのフォールバックルートに進む。
citation_pdf_url が -mmc1.pdf を返す当該論文のPDFがアーカイブされておらず、補足資料が解析されたBlood などのジャーナルでは「JATS全文はあるが本文PDFはアーカイブされていない」ことがある。すぐにPMCルートを諦め、補足資料を本文の代わりに使用しないこと(実測)。

★ IPレベルのレート制限が存在する(実測) 短時間にPMCに対してPDFを繰り返しリクエストする(例:連続して複数の論文をダウンロードする)と、正しいシンプルなUAを使用していても、直接reCAPTCHAに昇格される。45秒待っても回復しない。症状:「初回成功、その後すべて失敗」。 対応: ① バッチダウンロード時はリクエスト間に十分な間隔を空ける。② 一旦reCAPTCHA状態になったら、繰り返しリトライしない(ブロックが長期化するだけ)。代わりに他の作業を先に進めるか、経路4(supplementaryFiles)と出版社直リンクを使用する。③ どうしても複数論文が必要な場合は、事前にバッチで準備するのではなく、必要なときに都度ダウンロードすることを優先する。

★★ フォールバックルート:PMCがreCAPTCHAで使えない場合、出版社公式サイト経由に切り替える(実測で有効)

PMC直リンクが2回連続でreCAPTCHAに昇格された場合(IPレベルのレート制限、待機後も回復しない)、対象ジャーナルが完全OAジャーナルであれば、PMCをリトライし続けるよりも出版社公式サイト経由の方が信頼性が高い:

UA="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"
# 1) DOIを解決 → 最終的にどの出版社の記事ページに着地するかを確認
curl -s -o /dev/null -w "final: %{url_effective}\nHTTP: %{http_code}\n" -A "$UA" -L "https://doi.org/<DOI>"
# 2) 記事ページで実際のPDF直リンクを解析
curl -s -A "$UA" "https://<publisher-article-page>" | grep -oiE '<meta name="citation_pdf_url"[^>]*>|href="[^"]*\.pdf[^"]*"' | sort -u | head
# 3) Refererを付けて直接取得(出版社はRefererをほとんどチェックしないが、付けておくとより安定)
curl -sL --retry 3 -A "$UA" -e "$ARTICLE_PAGE" -o "$OUT" "$PDF_URL"

★★ 出版社ページがCloudflareで完全にブロックされている場合:ブラウザの「PDFに印刷」を使用する(実測で有効)

ashpublications.org(ASH系ジャーナル)は今回、Cloudflareによる完全なブロックが発生した。以前は有効だった「10秒待ってからopen」という経験則は再現できなかった。有効な代替経路:

  1. PMCの全文ページ(PDFではない)を開く。出版社サイトを迂回する。
  2. ブラウザツールでそのページをPDFに印刷する:agent-browser pdf
  3. reCAPTCHAが最初に表示された場合は、openをもう一度実行すれば通過できる。

判定のポイント:対象ジャーナルがASH / ScienceDirectのような強力なCloudflare防御を採用している場合、curlで繰り返しリトライしても成功確率は低く、ブロックを悪化させるだけ。ブラウザチャネルに直接切り替えること。

  • 動作確認済み:Haematologica / Ferrata Storti —— doi.org/10.3324/haematol.2025.287698 → haematologica.org/article/view/12187 → haematologica.org/article/download/12187/78653 → 2.91 MB / 14ページ。
  • 不可:Cloudflare系チャレンジでブロックされる出版社(ASH ashpublications.org、Wiley onlinelibrary.wiley.com/doi/pdfdirect/...、De Gruyter、Thieme)——これらはPMCチャネルまたはブラウザセッションに戻るしかない。
  • 事前判断:完全OA / Gold OA ジャーナルのみこのルートを試す価値がある(購読ジャーナルはペイウォールに当たり、迂回は禁止)。

★ 完全性チェック:大ファイルのダウンロードが中断されると xref が破損する

curl でPDFを取得中にSIGTERM / タイムアウトで中断された場合、ファイルヘッダは正常な %PDF-1.6 で、ファイルサイズも一見妥当だが、pdfinfo は Invalid XRef entry を報告する。したがってダウンロード後は、ファイルヘッダとファイルサイズだけを見て判断してはならず、以下の3つすべてが揃っていなければならない:

head -c 8 "$OUT"                                  # %PDF-…
tail -c 32 "$OUT" | od -c | tail -3               # startxref … %%EOF が表示されるはず
pdfinfo "$OUT" | grep -E "Pages|Page size"        # ページ数が「巻号ページ」から推定される数と一致するはず

この3つが全て揃って初めて完全とみなす。不足している場合は完全に再ダウンロードする(--retry 3 を追加)。破損したファイルを成果物として渡してはならない。

補足資料と画像

本文PDFが取得できない場合でも、supplementaryFiles エンドポイントは通常使用可能で、その内容はしばしば論文に付随する画像と補足方法である:

curl -sL -o sup.zip "https://www.ebi.ac.uk/europepmc/webservices/rest/PMC13049628/supplementaryFiles"
unzip -o sup.zip -d sup/

命名規則(Wiley / ASH系):*-gr1…*-grN は Figure 1…N に対応、*-ga1 はグラフィカルアブストラクト、*-mmc1.pdf は補足資料。

ブラウザツール使用時

クリック、ログイン、JSレンダリングが必要な場合にのみ agent-browser を使用すること。純粋なダウンロードシナリオではブラウザを起動しない——PoWはオフラインで解決可能であり、Chromiumを起動すると数百MBのオーバーヘッドと失敗の可能性が増えるだけ。どうしてもブラウザが必要な場合:

  • 使用可能なnodeがPATHに含まれていることを事前に確認する(そうしないとdaemonの起動がタイムアウトする)。
  • タスク終了後は必ず agent-browser close を実行し、ゾンビdaemonを残さない。

確認リスト

  • ダウンロード前に目的の文献がOAであることを確認する(または現在機関購読のIP範囲内にいることを確認する——この場合、出版社直リンクが直接使用できるが、それでも手動での単一ダウンロードに限り、バッチは禁止)。
  • 記事ページの citation_pdf_url から実際のPDFファイル名を解析する(main.pdf をハードコードしない)。
  • 保存後、ファイルヘッダが %PDF であることを確認する。
  • 末尾で startxref / %%EOF を確認する(大ファイルが中断されると、ヘッダは正常だがxrefが破損した半製品ができる。pdfinfo で識別可能)。
  • ページ数を検証する:re.findall(rb'/Count\s+(\d+)', data) または /Type /Page のカウントを使用する。file out.pdf のページ数は信頼しない(macOSでは

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

GreenWich-art/agent-skills

桌面 GUI 操作的统一编排入口。当用户要求操作一个只有图形界面的应用(改设置、点按钮、填表单、操作无 CLI/连接器的软件)时使用此 skill。提供四级能力:①路由决策——判断任务该走连接器、浏览器控制、Office 技能、命令行还是 computer use 桌面接管;②授权引导——检测并引导用户完成 macOS 辅助功能/屏幕录制权限授权,处理授权不生效等常见坑;③任务派发与验证——按目标/边界/失败处理三段式描述派发 GUI 任务,并以最终截图为准确认结果;④AX 兜底层——内置 axctl 工具做元素级无障碍读写(AXPress 语义点击,不碰鼠标不抢焦点),适用于 computer use 不可用或轻量场景。台前调度全场景实测(macOS 15 + 27.0.1 复检)。触发词:操控电脑、操作某个软件、点某个按钮、GUI 操作、电脑设置。

GreenWich-art/agent-skills

按学术论文规范(小三黑体一级标题/四号黑体二级/小四正文宋体1.5倍行距/三线表/中西文混排Times New Roman/统计量斜体) 批量重整 Markdown 或已有 docx 的格式。用户说"按学术格式排版""三线表""小三号黑体标题""1.5倍行距" "数字英文用Times New Roman""P值斜体"时使用。基于 python-docx 直接生成 docx,不走逐段插入。 不适用:高校课程论文/作业的字体字号约定(标准不同);党政机关公文国标 GB/T 9704 (又是另一套标准)。三套标准不可混用。

GreenWich-art/agent-skills

参考文献的 GB/T 7714-2015 著录规范化,以及 URL / DOI / PMID / PMC 链接的 可访问性批量核验与"假失效"识别。 触发场景: - 论文 / 综述 / 作业要交,需要核对参考文献格式 - "帮我按国标改一下参考文献" - 要交付一份文献清单,需要确认链接没死 - 已经有一堆 links,要批量验证哪些还能打开 含一个可复用脚本 `scripts/check_refs.py`,能自动判别 URL / DOI / PMID / PMC 并并发核验,且能区分「真死」与「被反爬」——后者不该判为失效。 不适用:从零生成一份带引文的正文(那是写作任务); Zotero 样式定制(见正文第六节,按需手工改 CSL)。

GreenWich-art/agent-skills

Local OCR using the macOS Vision framework. Triggers: OCR, 识别图片文字, 提取截图内容, 扫描件转文字, 图片转文字, 扫描版PDF转文字, read text from image/screenshot/photo/scanned PDF. Local-first and offline; prefer it over cloud OCR whenever data is sensitive or the machine is offline.

関連スキル