GreenWich-art/agent-skills

Télécharge des PDF d'articles biomédicaux en accès libre depuis PMC avec résolution de Preuve de Travail (Proof-of-Work) hors ligne. Déclencheurs : 下载文献PDF, PMC PDF, 403/404 sur le lien PDF, Préparation au téléchargement, page reCAPTCHA, texte intégral OA, fichiers supplémentaires, télécharger un PDF d'article.

Qu'est-ce que agent-skills ?

Cette compétence permet à un agent IA de télécharger automatiquement des articles de recherche biomédicale en accès libre (OA) au format PDF depuis la base de données PubMed Central (PMC). Elle résout hors ligne le défi Proof-of-Work (PoW) que PMC impose parfois avant de fournir le PDF, évitant ainsi les reCAPTCHA coûteux. Idéale pour les agents comme Claude Code, Cursor ou Codex, elle comprend une chaîne de dégradation complète : elle essaie d'abord EuropePMC pour le texte intégral structuré, puis Unpaywall pour localiser le PDF, ensuite la résolution PoW de PMC, les fichiers supplémentaires, et enfin les liens directs des éditeurs (avec gestion des blocages Cloudflare et des abonnements institutionnels). La compétence extrait d'abord le nom réel du fichier PDF depuis la page de l'article (via `citation_pdf_url`), résout le PoW en calculant un nonce tel que `sha256(challenge + nonce)` commence par un certain nombre de zéros, puis télécharge le PDF en utilisant un User-Agent minimal et des cookies frais. Elle vérifie l'intégrité du fichier (en-tête `%PDF`, `startxref`/`%%EOF`, nombre de pages) et gère les erreurs courantes comme les noms de fichiers incorrects ou le blocage IP par PMC (avec des itinéraires de contournement via les éditeurs ou l'impression depuis le navigateur).

Compatible avec~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 Recherche et analyse de données skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Obtention de PDF d'articles PMC / OA

Conditions préalables

Utilisation réservée aux articles en accès libre (OA) (CC BY / CC BY-NC / CC BY-NC-ND, etc.). Ne pas utiliser pour contourner les paywalls des articles sous abonnement — cela constitue un contournement de la protection des droits d'auteur. Vérifier le statut OA : Unpaywall renvoie is_oa: true, ou EuropePMC renvoie isOpenAccess: Y.

Scénario d'abonnement institutionnel (complément important)

Lorsque l'université/l'établissement de l'utilisateur est abonné aux bases de données des éditeurs, le téléchargement manuel d'un seul article est totalement conforme dans le cadre des droits d'accès, mais il faut noter :

  • Sur le réseau du campus / dans la plage IP de l'établissement : l'éditeur reconnaît l'IP, pas l'utilisateur. Le niveau 5 de la chaîne de dégradation (lien direct de l'éditeur) renvoie généralement un 200 directement, et Cloudflare ne bloque pas non plus — dans ce cas, le pipeline existant de cette compétence peut obtenir le contenu sous abonnement sans aucune logique de connexion.
  • Accès hors campus : privilégier le VPN système fourni par l'établissement (transparent pour les scripts, configurable une fois) ; les WebVPN (proxies de réécriture d'URL) ne sont pas pris en charge par cette compétence en raison des règles de réécriture différentes selon les établissements et de la nécessité de conserver les cookies de session.
  • Ne pas écrire de connexion automatique Shibboleth / OpenAthens : nécessite le stockage local d'identifiants d'authentification unifiés, ce qui est un risque de sécurité ; de plus, les flux IdP varient considérablement d'un établissement à l'autre, rendant une implémentation générique impossible.
  • Ligne rouge du téléchargement en masse : presque toutes les licences institutionnelles des éditeurs distinguent le « téléchargement manuel d'un seul article » du systematic/bulk downloading. Même avec un abonnement, la récupération en masse par script viole les termes de la licence et peut entraîner le bannissement de toute la plage IP de l'établissement. Si un besoin réel d'extraction de texte intégral à grande échelle se présente, il faut demander l'API TDM (Text Mining) de l'éditeur (par exemple, Elsevier TDM API, Springer Nature Meta API) et passer par les canaux de quota officiels, plutôt que d'utiliser cette compétence pour des boucles en masse.

Chaîne de dégradation (strictement dans l'ordre)

PrioritéMéthodeCommande / Point d'accèsDescription
1Texte intégral structuré EuropePMChttps://www.ebi.ac.uk/europepmc/webservices/rest/{PMCID}/fullTextXMLLe plus stable. Utilisé pour extraire une structure de texte intégral précise jusqu'au niveau des sous-titres. Renvoie JATS XML
2Unpaywall localise la position OAhttps://api.unpaywall.org/v2/{DOI}[email protected]Lit oa_locations[].url_for_pdf, donne directement le lien direct PDF
3Résolution PoW PMC et téléchargementscripts/pmc_pdf.py <PMCID> <out.pdf>Voir ci-dessous. Solution principale pour obtenir le PDF du corps de l'article
4Fichiers supplémentaires EuropePMChttps://www.ebi.ac.uk/europepmc/webservices/rest/{PMCID}/supplementaryFilesRenvoie un ZIP : images originales (gr1…=Figure 1…)+ PDF de matériel supplémentaire (mmc1.pdf)
5Lien direct éditeur.../article-pdf/... selon l'éditeurGénéralement 403 (Cloudflare). À essayer en dernier

Points d'accès confirmés comme obsolètes (ne pas perdre de temps)

  • …/rest/{PMCID}/fullTextPDF → 404 (obsolète)
  • …/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 (le service OA a migré)
  • Les pages d'articles de ashpublications.org restent bloquées sur la page de défi Cloudflare « Veuillez patienter… » dans un navigateur sans tête, inutilisable

★ Condition préalable : le nom du fichier PDF sur PMC n'est pas fixe, il faut d'abord l'analyser

Le <nom_fichier>.pdf dans https://pmc.ncbi.nlm.nih.gov/articles/{PMCID}/pdf/<nom_fichier>.pdf varie selon la revue et l'année. Coder en dur main.pdf aboutit à une 404 dans la plupart des cas.

Revue testéeNom de fichier réel
Am J Hematolmain.pdf
Blood Advancesmain.pdf
HemaSphereHEM3-10-e70338.pdf
Am J HematolAJH-101-1790.pdf
Liver InternationalLIV-46-0.pdf
Haematologica111300.pdf (volume 111 + page de début 300, abréviation de la revue omise)
Blood (manuscrit NIH)nihms-2192199.pdf

Méthode d'analyse (par priorité ; tous les cas testés ont correspondu à la règle 1)

  1. Balise <meta name="citation_pdf_url" content="https://pmc.ncbi.nlm.nih.gov/articles/{PMCID}/pdf/XXX.pdf"> sur la page de l'article ← Le plus fiable
  2. grep -oE 'href="[^"]*?/pdf/[^"]+?\.pdf"' prendre la première occurrence
  3. Repli pdf/main.pdf

Conventions de nommage (non fiables, à utiliser uniquement pour juger manuellement si l'analyse est correcte) : les OA de Wiley sont souvent <abréviation revue>-<volume imprimé>-0.pdf (ex. LIV-46-0.pdf) ; avec numéro d'article <abréviation revue>-<volume>-<numéro article>.pdf (ex. HEM3-10-e70338.pdf) ; pour la même revue, souvent <abréviation>-<volume>-<page début>.pdf (ex. AJH-101-1790.pdf) ; il existe aussi des variantes « volume+page de début, sans abréviation de la revue » (comme pour Haematologica 111300.pdf = volume 111 + page de début 300).

Lors de la récupération de la page de l'article, veillez à jeter les cookies : utilisez une requête indépendante, sans conservation des cookies, pour lire la page de l'article. La requête PDF doit également être lancée depuis une session de cookies entièrement nouvelle. Si les ncbi_sid / ncbi_pinger générés par la page de l'article sont transmis à la requête PDF, celle-ci sera immédiatement dégradée en reCAPTCHA (testé). scripts/pmc_pdf.py implémente déjà cela.

Solution principale : résolution hors ligne du Proof-of-Work PMC

Principe

https://pmc.ncbi.nlm.nih.gov/articles/{PMCID}/pdf/<nom_fichier>.pdf peut basculer entre deux types de pages de défi selon la stratégie de risque :

  • Page PoW (1817 octets, titre Preparing to download ...) → Résoluble hors ligne, c'est le canal que nous voulons.
  • Page reCAPTCHA (environ 20 Ko, titre contenant reCAPTCHA) → Impossible à résoudre hors ligne.

Clé pour déclencher PoW plutôt que reCAPTCHA : utiliser un UA minimal, et ne pas visiter la page de l'article avant de demander le PDF.

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

Contre-exemples (conduisent à une dégradation en reCAPTCHA, testé) :

  • UA Chrome complet (…AppleWebKit/537.36 … Chrome/1xx.0.0.0 Safari/537.36)
  • GET de la page de l'article d'abord (en transportant ncbi_sid / ncbi_pinger) puis demande du PDF

Algorithme PoW (rétroconception de pow-*.js, confirmée)

La page PoW intègre quatre constantes : POW_CHALLENGE / POW_DIFFICULTY / POW_COOKIE_NAME / POW_COOKIE_PATH.

  1. Trouver le plus petit entier non négatif nonce tel que sha256(challenge + str(nonce)).hexdigest() ait un préfixe égal à '0' * difficulty ;
  2. Définir le cookie : <POW_COOKIE_NAME> = challenge + "," + nonce (chemin = POW_COOKIE_PATH) ;
  3. Renvoyer la demande au lien direct PDF avec ce cookie et Referer: https://pmc.ncbi.nlm.nih.gov/articles/{PMCID}/ → Renvoie normalement 200 et Content-Type: application/pdf.

difficulty = 4 typique (environ 65536 hachages attendus, terminé en moins d'une seconde en local).

Script en une commande

# Recommandé : analyse automatique du nom de fichier PDF réel (via citation_pdf_url), puis résolution hors ligne du PoW
python3 scripts/pmc_pdf.py PMC13575452 ./out.pdf

# Si le nom de fichier a déjà été analysé, il peut être spécifié directement, en sautant la requête de la page de l'article
python3 scripts/pmc_pdf.py PMC13575452 ./out.pdf --pdf-name LIV-46-0.pdf

# Mode silencieux (affiche uniquement la ligne de résultat)
python3 scripts/pmc_pdf.py PMC13575452 ./out.pdf --quiet

Comportement du script : d'abord, demande la page de l'article avec un UA minimal et en jetant les cookies pour analyser le lien direct PDF réel → puis fait une demande à froid de ce PDF avec une session de cookies entièrement nouvelle → si le PDF est obtenu directement, il est sauvegardé ; sinon, les constantes PoW sont analysées, résolues, le cookie est renseigné et la tentative est répétée. Pour forcer une nouvelle récupération du challenge, relancez simplement le script (le script ne sauvegarde pas les cookies sur le disque, chaque session est nouvelle).

★★ Deux règles strictes à retenir (leçons douloureuses testées sur le terrain)

1. Le deuxième paramètre positionnel est le chemin complet du fichier de sortie, pas un répertoire. Passer un répertoire déclenchera une erreur IsADirectoryError: [Errno 21] Is a directory après avoir déjà obtenu le PDF, rendant la résolution PoW et le PDF inutiles. ❌ pmc_pdf.py PMC13482240 --outdir /path/to/dir  ✅ pmc_pdf.py PMC13482240 /path/to/dir/xxx.pdf

2. Le canal PDF de PMC a une caractéristique de « une seule chance ». La première demande à froid réussit généralement le PoW et obtient le vrai PDF ; si l'on demande à nouveau le même PDF immédiatement après, il sera presque certainement dégradé en reCAPTCHA (pas une simple limitation de débit « changez d'UA »). Par conséquent, le chemin de sortie doit être correct du premier coup, ne faites absolument pas de « test de lancement pour voir ». Testé : premier tour status=200 type=application/pdf bytes=23970819, quelques secondes plus tard, en relançant la même URL, on obtient type=text/html bytes=21329 (page de défi reCAPTCHA). Une fois cette opportunité gaspillée, passez directement à la section suivante « Route de dégradation via le site de l'éditeur », ne réessayez pas sur PMC.

Diagnostic des pannes

PhénomèneCauseAction
Retourne du HTML contenant POW_CHALLENGECanal PoW activé (normal)Confier la résolution au script
Retourne du HTML contenant recaptchaDégradé en reCAPTCHAChanger pour un UA minimal, vider les cookies de session, attendre un peu et réessayer ; si toujours en échec, utiliser les voies 4/5
404 / « Article not found »Le nom du fichier PDF est mal devinéRevenir à la page de l'article pour analyser citation_pdf_url, ne pas coder en dur main.pdf
nonce ne converge pas longtempsdifficulty a été augmentéAfficher difficulty pour juger ; si >5, envisager une résolution asynchrone ou multi-processus
Résolution réussie mais le PDF est toujours du HTMLDomaine/chemin du cookie inadaptéVérifier que le domaine du cookie est pmc.ncbi.nlm.nih.gov et que le chemin prend POW_COOKIE_PATH
IsADirectoryError: Is a directoryLe paramètre de sortie a été traité comme un répertoireLe deuxième paramètre est le chemin complet du fichier de sortie. Le PDF a en fait déjà été obtenu, mais pas sauvegardé — ne relancez pas immédiatement (cela déclencherait un reCAPTCHA). Corrigez d'abord le chemin. Si déjà dégradé, passez directement à la route du site de l'éditeur
Première réussite, deuxième reCAPTCHA immédiatLimitation de débit « une seule chance » de PMC pour le même chemin de PDFVoir la règle stricte 2 ci-dessus ; abandonnez PMC, passez à la route de dégradation via le site de l'éditeur
citation_pdf_url renvoie -mmc1.pdfLe PDF de l'article n'est pas en base, la balise pointe vers du matériel supplémentaireCommun pour les revues comme Blood où « le texte intégral JATS existe mais le PDF du corps de l'article n'est pas en base ». Abandonnez immédiatement la route PMC, ne faites pas passer du matériel supplémentaire pour le corps de l'article (testé)

★ Il existe une limitation de débit au niveau IP (testé) Après avoir répété les demandes de PDF à PMC sur une courte période (par exemple, téléchargement consécutif de plusieurs articles), même avec le bon UA minimal, on est directement dégradé en reCAPTCHA, et l'attente de 45 s ne rétablit pas la situation. Se manifeste par « première réussite, puis tous les échecs ». Action : ① Lors d'un téléchargement en masse, laissez un intervalle suffisant entre deux demandes ; ② Une fois en état reCAPTCHA, ne réessayez pas à plusieurs reprises (cela ne fera qu'allonger le bannissement), passez plutôt à d'autres tâches, ou utilisez la voie 4 (supplementaryFiles) et les liens directs des éditeurs ; ③ Si vous avez vraiment besoin de plusieurs articles, privilégiez le téléchargement à la demande plutôt que le préchauffage en masse.

★★ Route de dégradation : quand PMC est bloqué par reCAPTCHA, passer par le site de l'éditeur (testé et efficace)

Lorsque le lien direct PMC a été dégradé en reCAPTCHA deux fois (limitation de débit IP, ne se rétablit pas après attente), si la revue cible est entièrement OA, passer par le site de l'éditeur est plus fiable que de continuer à réessayer PMC :

UA="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"
# 1) Résolution DOI → observer la page d'article finale de l'éditeur
curl -s -o /dev/null -w "final: %{url_effective}\nHTTP: %{http_code}\n" -A "$UA" -L "https://doi.org/<DOI>"
# 2) Analyser le lien direct PDF réel sur la page de l'article
curl -s -A "$UA" "https://<publisher-article-page>" | grep -oiE '<meta name="citation_pdf_url"[^>]*>|href="[^"]*\.pdf[^"]*"' | sort -u | head
# 3) Récupérer directement avec Referer (les éditeurs ne vérifient presque jamais le Referer, mais le mettre est plus sûr)
curl -sL --retry 3 -A "$UA" -e "$ARTICLE_PAGE" -o "$OUT" "$PDF_URL"

★★ Quand le site de l'éditeur est complètement bloqué par Cloudflare : utiliser l'impression du navigateur en PDF (testé et efficace)

ashpublications.org (revues du groupe ASH) a subi un blocage complet par Cloudflare lors de cette session, L'expérience précédente « attendre 10 s puis ouvrir » n'a pas pu être reproduite. Chemin alternatif efficace :

  1. Ouvrir la page de texte intégral de PMC (pas le PDF), contournant le site de l'éditeur
  2. Utiliser l'outil d'impression du navigateur pour imprimer cette page en PDF : agent-browser pdf
  3. Lors du premier affichage du reCAPTCHA, exécuter à nouveau open une fois pour passer

Point de décision : lorsque la revue cible est fortement protégée par Cloudflare (comme ASH / ScienceDirect), ne réessayez pas avec curl — le taux de réussite est faible et cela aggrave le bannissement. Passez directement au canal navigateur.

  • Vérifié comme faisable : Haematologica / Ferrata Storti —— doi.org/10.3324/haematol.2025.287698 → haematologica.org/article/view/12187 → haematologica.org/article/download/12187/78653 → 2.91 Mo / 14 pages.
  • Pas faisable : revues encore bloquées par des défis de type Cloudflare (ASH ashpublications.org, Wiley onlinelibrary.wiley.com/doi/pdfdirect/..., De Gruyter, Thieme) — elles ne peuvent être traitées que par le canal PMC ou par une session navigateur.
  • Pré-évaluation : seules les revues entièrement OA / Gold OA méritent de tenter cette route (les revues sous abonnement rencontreront un paywall qu'il est interdit de contourner).

★ Vérification d'intégrité : les téléchargements interrompus de gros fichiers entraînent une corruption xref

Si le téléchargement du PDF par curl est interrompu par SIGTERM / timeout, l'en-tête du fichier reste normal %PDF-1.6, la taille semble raisonnable, mais pdfinfo signalera Invalid XRef entry. Par conséquent, après le téléchargement, ne vous fiez pas uniquement à l'en-tête et à la taille du fichier ; il faut vérifier simultanément :

head -c 8 "$OUT"                                  # %PDF-…
tail -c 32 "$OUT" | od -c | tail -3               # devrait montrer startxref … %%EOF
pdfinfo "$OUT" | grep -E "Pages|Page size"        # Le nombre de pages doit correspondre à celui déduit du « volume/numéro/page »

Ces trois éléments doivent être complets pour que le fichier soit considéré comme intègre ; en cas de manque, recommencer le téléchargement complet (avec --retry 3), ne pas livrer un fichier corrompu.

Matériel supplémentaire et images

Lorsque le PDF du corps de l'article est inaccessible, le point d'accès supplementaryFiles est généralement toujours disponible, et son contenu correspond souvent aux images et méthodes supplémentaires de l'article :

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

Conventions de nommage (Wiley / ASH) : *-gr1…*-grN correspondent aux Figures 1…N, *-ga1 au résumé graphique, *-mmc1.pdf au matériel supplémentaire.

Utilisation des outils navigateur

N'utiliser agent-browser que lorsque des clics, une connexion ou un rendu JS sont nécessaires. Ne pas lancer le navigateur pour des téléchargements purs — le PoW peut être résolu hors ligne, lancer Chromium n'ajoute que des centaines de Mo de surcharge et une surface d'échec. Si un navigateur est vraiment nécessaire :

  • Vous devez d'abord avoir un nœud disponible dans le PATH (sinon le démon dépasse le délai d'attente) ;
  • Assurez-vous de fermer le navigateur à la fin de la tâche avec agent-browser close pour éviter les démons zombies.

Liste de vérification

  • Avant le téléchargement, confirmer que l'article cible est OA (ou confirmer que l'on se trouve dans la plage IP de l'abonnement institutionnel — dans ce cas, le lien direct de l'éditeur peut être utilisé directement, mais toujours uniquement pour un téléchargement manuel d'un seul article, pas en masse)
  • Analyser le nom de fichier PDF réel à partir de citation_pdf_url sur la page de l'article (ne pas coder en dur main.pdf)
  • Après la sauvegarde, vérifier que l'en-tête du fichier est %PDF
  • Vérifier la fin avec startxref / %%EOF (un fichier volumineux interrompu peut avoir un en-tête normal mais une structure xref corrompue ; pdfinfo le détectera)
  • Vérifier le nombre de pages : utiliser re.findall(rb'/Count\s+(\d+)', data) ou compter /Type /Page, ne pas faire confiance au nombre de pages de file out.pdf (souvent erroné comme « 1 pages » sur macOS) ; on peut aussi utiliser mdls -name kMDItemNumberOfPages
  • Extraire la première et la dernière page pour vérifier le contenu (pdftotext -f 1 -l 1 / -f N -l N), confirmer qu'il ne s'agit pas de matériel supplémentaire ou d'un autre article
  • Enregistrer le PMCID / DOI / chemin de sauvegarde pour faciliter la vérification ultérieure
  • En cas d'échec, expliquer honnêtement la raison de l'échec, ne pas présenter du matériel supplémentaire ou des images comme le PDF du corps de l'article

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.

Skills associés