Nature Literature Downloader
此技能将文献通过合法开放获取、出版商API、CNKI机构和基于浏览器的机构提供者进行路由。scripts/batch_download.mjs 是编排入口点;学校配置、出版商凭据、元数据/OA解析、提供者下载、内容验证和清单是独立的模块。
已验证的路由是示例,而非默认设置。每个机构应从用户实际的图书馆资源URL开始,因为资源门户、CAS回调、EZproxy、WebVPN、IP认证数据库页面和数据库详情页比学校名称更能可靠地揭示实时授权路径。
SI确认门——首先执行此操作。 在下载任何PDF、CAJ、HTML、XML、档案或附件之前,询问用户是否需要支持信息。明确要求SI算作是;明确要求仅正文算作否。否则对整个批次询问一次。使用
--si或--no-si之一运行下载器。如果两个标志都没有,脚本返回si_confirmation_required且不创建输出目录。
主要工作流程。 在路由前规范化DOI/标题并识别语言和出版商。中文文献始终使用CNKI。对于英文Elsevier、Springer Nature和IEEE文章,若有可用的提供者凭据,首先尝试出版商API,在API下载成功后不需要进行OA判定。如果该API尝试失败,自动检查合法的OA来源。其他英文出版商首先检查OA,然后当OA不可用时使用机构Web Access路由。
规范化 DOI/题名并识别语言、出版商
├─ 中文文献:直接走 CNKI
└─ 英文文献
├─ Elsevier / Springer Nature / IEEE,且已配置有效 Key
│ ├─ 优先通过出版商 API 下载
│ ├─ API 下载成功:结束,不强制判断 OA
│ └─ API 下载失败:检查文章级 OA,再走 PMC / Unpaywall / 合法仓储
└─ 其他出版商
├─ 检查文章级 OA
└─ OA 不可用:走 Web Access 机构授权
中文文献仅限CNKI。 中文标题、
zh元数据语言、显式的CNKI源URL或--route cnki必须使用CNKI,即使似乎存在其他OA副本。重用用户当前的Chrome库/CNKI登录状态,并优先配置的discovery.cnki_url。切勿导出cookies或收集机构密码。
出版商API回退。 有效的API密钥不保证全文访问权限。当Elsevier、Springer Nature或IEEE的API尝试返回无访问权限或无法使用的全文时,自动首先尝试合法OA来源。如果出版商API和OA路由都失败,返回
api_fallback_confirmation_required并询问一次是否使用Web Access。不要自动切换到机构Web Access。
浏览器状态原则。 授权下载依赖于用户登录的确切浏览器配置文件。如果代理、CDP会话或浏览器自动化工具打开了一个新的配置文件或没有登录状态的浏览器,不要将失败视为缺少库权限。切换到重用用户活动浏览器会话的控制路径,或要求用户在受控浏览器实例中进行身份验证。
格式原则。 PDF、HTML全文和数据库原生格式(如CAJ)是不同的交付物。如果用户只请求PDF,要求真正的PDF链接或
no_authorized_pdf_found/pdf_fetch_failed。不要将CAJ、HTML或登录页面保存为PDF。
下载接收和首次运行配置
对于每个下载请求,首先建立论文列表并询问:
是否同时下载这些文献的 Supporting Information(SI,补充材料)?
仅在需要识别请求的论文时才在此问题之前进行元数据查找。在知道答案之前不要下载文件。仅当所选路由为CNKI或Web Access时配置库。仅当所选英文文章属于Elsevier、Springer Nature或IEEE时配置出版商API;在尝试配置的提供者API之前不需要进行OA判定。
付费库资源配置
询问用户实际使用的库资源URL:
请发你平时进入图书馆电子资源/数据库的平台链接。
可以是资源门户、数据库列表、Web of Science 入口、某个数据库详情页,
或跳转到统一身份认证的登录链接。
在保存配置之前从URL推断授权路由:
python3 scripts/configure_school.py infer "https://example.edu/library/resources"
python3 scripts/configure_school.py url "https://example.edu/library/resources"
python3 scripts/configure_school.py show
python3 scripts/configure_school.py health --force
分发的技能不包含任何学校预设。如果用户无法提供资源URL,要求他们找到其机构的库/数据库入口,而不是猜测特定学校的域名。
默认配置路径为:
~/.config/lit-dl/school.json
对于测试或隔离配置文件,设置:
LIT_DL_CONFIG_DIR=/path/to/configdir
下载器自动读取此配置。如果存在 discovery.web_of_science_url,scripts/batch_download.mjs 将其用作Web of Science入口;否则回退到 https://www.webofscience.com/wos/woscc/basic-search。
对于中文文献,下载器还会读取 discovery.cnki_url(如果存在)。如果不存在,scripts/batch_download.mjs --title "<中文题名>" 回退到 https://kns.cnki.net/kns8s/defaultresult/index。
固定出版商API接入输出
在库资源URL已保存、显示并通过健康检查后,立即输出以下Markdown块。不要用搜索结果替换URL,不要缩短IEEE警告,不要要求用户将API密钥粘贴到聊天中。
请按需配置以下出版商,即可实现长期稳定下载
Elsevier API Key(必配置)
[https://dev.elsevier.com/apikey/manage](https://dev.elsevier.com/apikey/manage)
Website URL可以填写:[Yuan1z0825/nature-skills](https://github.com/Yuan1z0825/nature-skills)
Springer Nature Developer Portal(建议配置)
https://dev.springernature.com/#api
下滑依次点击**Subscribe now“-“free”**
IEEE Developer Registration(按需)
[https://developer.ieee.org/member/register](https://developer.ieee.org/member/register)
完成登录/注册及“学校邮箱”验证后,进入 API Management 页面复制 API Key。IEEE 普通 Key 仅用于 Metadata API,全文访问需要单独申请 Full-Text Access。
显示此块后停止,并等待用户完成注册、学校邮箱验证和复制相关API密钥。用户执行所有密码、CAPTCHA、OTP、电子邮件确认、同意和API密钥复制步骤。切勿从浏览器页面读取API密钥,或要求用户通过聊天发送它们。
API优先和开放获取回退
对于英文文章,在决定何时解析文章级OA之前识别其出版商:
-
收集DOI、PMID、确切标题、文章URL或确定的论文列表,然后规范化其元数据和出版商。
-
如果属于Elsevier、Springer Nature或IEEE,并且配置了可用的提供者凭据,首先尝试该出版商API。成功后,记录
accessMode: publisher_api和oa_status: not_checked_api_first;不要运行OA解析只是为了标记文章。 -
如果出版商API失败,自动搜索合法的OA来源,如PMC、Unpaywall、出版商OA页面、arXiv及其他合法仓储或明确的开放PDF URL。在清单中保留失败的API尝试。
-
对于所有其他英文出版商,在Web Access之前搜索那些合法OA来源。
-
对于确切标题或显式的仅OA请求,优先使用:
node scripts/batch_download.mjs --title "<exact title>" --open-access --no-si --out "<project>"当用户提供已知的合法OA PDF URL时,使用
--pdf-url。 -
验证下载的文件并记录来源。将成功的PDF标记为
open_access_downloaded。 -
如果未找到合法OA全文,标记
oa_not_found。对于已失败的受支持出版商,在Web Access之前请求确认。对于其他出版商,继续到Web Access。如果明确请求了--route open_access,在OA结果后停止。
出版商API凭据
在固定的出版商接入块之后,仅配置用户已获得API密钥的提供者。让用户通过本地隐藏提示输入每个密钥:
python3 scripts/configure_credentials.py set elsevier
python3 scripts/configure_credentials.py set springer_nature
python3 scripts/configure_credentials.py set ieee --fulltext-endpoint 'https://issued-endpoint.example/articles/{doi}'
python3 scripts/configure_credentials.py show
python3 scripts/configure_credentials.py validate <provider>
python3 scripts/configure_credentials.py delete <provider>
python3 scripts/configure_credentials.py contact-email [email protected]
仅使用上面固定接入块中的注册URL。让用户通过本地隐藏提示输入每个密钥;切勿回显或将其放入清单中。IEEE元数据API访问不是付费全文访问;在将IEEE视为可通过API下载之前,需要已发布的全文访问端点/模板。秘密存储在 ~/.config/lit-dl/credentials.json,模式为 0600。
资源URL分流
在选择访问路径之前对用户提供的URL进行分类:
cas.* / /authserver/login CAS / SSO 登录页面;检查 service= 回调,然后返回到服务门户
idp/shibboleth / carsi CARSI / Shibboleth 机构路由
ezproxy / libproxy EZproxy 远程访问代理
webvpn / vpn WebVPN 路由
metaersp / metaauth / uas 库资源聚合门户
webofscience / sciencedirect 数据库或出版商入口;检查是否通过门户到达
如果URL是带有 service= 参数的登录页面,将回调主机视为资源服务,不要让登录页面成为整个工作流程。例如,https://login.university.example/authserver/login?service=https://resources.university.example/callback 意味着身份服务在身份验证后返回到用户的资源门户。
机构特定域名
对照用户地址栏中实际显示的内容进行确认;为每个机构纠正这些内容,而不是假设预设是完整的。
Library home / aggregation: library.example.edu, resources.example.edu
Discovery/database entry: webofscience.com, clarivate.com, cnki.net, sciencedirect.com, provider.example.com
Unified identity / SSO: sso.example.edu, cas.example.edu, idp.example.edu
Federation / WAYF: ds.carsi.edu.cn, wayf.example.org, shibboleth/openathens hosts
Proxy / WebVPN: ezproxy.example.edu, webvpn.example.edu
将已配置的机构登录、联合、代理和数据库登录主机视为登录阶段。不要将到达它们视为最终失败。
边界
仅使用用户的合法机构访问权限。不要绕过付费墙、DRM或双因素认证。
验证优先规则: 当用户的已认证Chrome会话中出现可见的滑块、复选框、机器人检查或简单验证控件时,在浏览器中尝试它,然后再要求用户干预。保持尝试限定(在一个标签页上最多两次尝试),验证挑战已消失,并在成功后从同一标签页继续。
- 滑块/拖动挑战(包括CNKI拼图滑块):估计可见的移动距离并模拟逐渐拖动。
- ScienceDirect机器人检查、托管Turnstile和reCAPTCHA复选框阶段:尝试一次可见的复选框。
- 简单的
Continue、Verify或等效的可见控件:点击一次,然后重新检查页面状态。
用户移交: 仅在限定尝试失败后要求用户,或当页面需要秘密或身份识别的输入(如图像选择答案、QR码批准、短信/OTP、口令、硬件密钥或双因素认证)时立即要求。保持受挑战的标签页打开,切勿要求用户将凭据或代码粘贴到聊天中。
避免无限制或 indiscriminate 的下载。仅处理用户确认的确定论文列表,应用提供者友好的节奏,并留下清晰的审计跟踪,说明下载了什么、从何处下载以及是否找到了支持信息。
不要要求用户将机构密码、数据库密码、OTP代码、恢复代码或会话令牌粘贴到聊天或终端中。如果用户提供密码,请拒绝并使用移交登录工作流程。
已保存的机构登录页面例外:如果用户明确表示浏览器已填写凭据并授权点击可见的登录/确认按钮,则代理可以在预期的机构SSO / CAS / CARSI / Shibboleth页面上点击该按钮一次,无需读取、复制或键入任何凭据。此例外不适用于CAPTCHA、QR码登录、短信/OTP、出版商机器人检查、同意/安全警告或预期机构登录流程之外的任何页面。
不要检查或导出cookies、密码、本地存储、浏览器配置文件或会话文件。仅使用浏览器已认证的页面上下文。
前提条件
在尝试下载之前,确认适用于所选访问分支的条件。
对于仅OA分支,确认目标论文标识符/列表、输出文件夹、Node.js 22+以及当PDF验证需要时的Python 3。不需要库配置或机构浏览器登录。
对于付费库分支,确认这些条件:
- 包含用户库/数据库登录状态的浏览器在用户的机器上打开。
- 学校配置存在且有效。
- 运行
python3 scripts/configure_school.py show。 - 如果缺失,运行
python3 scripts/configure_school.py preset "<学校名称>"或引导用户通过src/wizard.py。
- 运行
- 用户已亲自登录到其机构