跳到主要内容

OAI-PMH

开放档案元数据收割协议(Open Archives Initiative Protocol for Metadata Harvesting,简称 OAI-PMH) 是图书馆、发现服务、机构知识库和学术索引机构用于收集出版物元数据的标准协议。

Academic Stack 针对已发表的期刊文章提供了 OAI-PMH 2.0 接口端点。该端点暴露 Dublin Core(都柏林核心)元数据,并支持完全收割与增量收割。

仅限元数据

OAI-PMH 仅分发书目元数据。它不会传输文章 PDF,也不能替代 DOI 注册、Crossref 提交、站点地图或 Google Scholar 元数据。

示例域名

本指南使用 https://www.publisher.com 作为出版社域名示例,使用 https://www.yourjournal.com 作为期刊域名示例。请将这些域名以及 {journal_slug} 等占位符替换为您实际部署的域名和期刊标识。

存储库接口 URL

可用的存储库接口 URL 取决于 Academic Stack 的部署类型。

企业版 / 单出版社部署

出版社级存储库包含来自所有公开期刊的文章:

https://www.publisher.com/oai

每个公开期刊也拥有独立的存储库:

https://www.publisher.com/journal/{journal_slug}/oai

例如:

https://www.publisher.com/journal/nature-science/oai

出版社级存储库使用 OAI 集(setSpec)来区分不同期刊。期刊级存储库仅包含所选期刊。

云服务 PaaS / SaaS 部署

每个期刊域名均代表一个独立的 OAI-PMH 存储库:

https://www.yourjournal.com/oai

接口仅返回属于从当前域名解析出的期刊的文章。无法通过提供期刊 ID 或 slug 来访问其他期刊。

在 PaaS / SaaS 部署模式下,不存在出版社级或全平台级的存储库。

快速验证

请在浏览器或 OAI-PMH 验证工具中打开以下 URL:

https://www.yourjournal.com/oai?verb=Identify
https://www.yourjournal.com/oai?verb=ListMetadataFormats
https://www.yourjournal.com/oai?verb=ListRecords&metadataPrefix=oai_dc

成功的响应应当为根节点是 <OAI-PMH> 的 XML,且 HTTP Content-Type 为:

Content-Type: application/xml; charset=UTF-8

支持的 OAI-PMH 请求

Academic Stack 支持全部六种 OAI-PMH 2.0 谓词(Verbs)。

谓词用途必需 / 允许参数
Identify返回存储库名称、基础 URL、管理员邮箱、时间戳策略和协议信息。
ListMetadataFormats列出存储库支持的元数据格式。可选 identifier
ListSets列出出版社级存储库中的期刊集。
ListIdentifiers返回记录头信息,不包含 Dublin Core 元数据。metadataPrefixresumptionToken
ListRecords返回记录头信息和 Dublin Core 元数据。metadataPrefixresumptionToken
GetRecord根据其 OAI 标识符返回一条记录。identifier, metadataPrefix

接口同时支持 HTTP GETPOST 请求。

元数据格式

Academic Stack 当前支持:

metadataPrefix=oai_dc

oai_dc 响应使用标准的 Dublin Core 命名空间:

http://www.openarchives.org/OAI/2.0/oai_dc/

字段映射对照表

文章元数据映射如下:

Academic Stack 字段Dublin Core 元素
文章标题dc:title
每位作者dc:creator (每位作者对应一个元素)
每个关键词dc:subject (每个关键词对应一个元素)
摘要dc:description
出版商名称dc:publisher
出版或在线发表日期dc:date
文章类型dc:type
DOI 链接dc:identifier
文章详情页 URLdc:identifier
期刊、卷、期和页码dc:source
期刊语言dc:language

注:仅暴露属于公开期刊且处于公开、非删除状态的文章。

OAI 标识符

每篇文章都会分配一个稳定的 OAI 标识符:

oai:{PROJECT_NAME}:article:{article_id}

例如:

oai:academic_stack:article:345

标识符独立于:

  • 期刊域名
  • 期刊 slug
  • DOI 变更
  • 卷和期分配
  • 文章详情页 URL

OAI 标识符用于标识元数据记录本身。它不是 DOI,也不是文章 URL。DOI 和详情页 URL 作为 dc:identifier 值单独提供。

请求示例:

https://www.yourjournal.com/oai?verb=GetRecord&metadataPrefix=oai_dc&identifier=oai:academic_stack:article:345

时间戳与增量收割

OAI 头部中的 <datestamp> 表示文章记录元数据的更新时间(UTC):

<datestamp>2026-07-30T08:30:00Z</datestamp>

存储库采用秒级精度:

YYYY-MM-DDThh:mm:ssZ

收割工具可以请求在特定日期范围内更新的记录:

https://www.yourjournal.com/oai?verb=ListRecords&metadataPrefix=oai_dc&from=2026-07-01T00:00:00Z
https://www.yourjournal.com/oai?verb=ListRecords&metadataPrefix=oai_dc&from=2026-07-01T00:00:00Z&until=2026-07-30T23:59:59Z

fromuntil 边界均包含在内(闭区间)。两个值都必须使用存储库的完整 UTC 时间戳格式,且 from 不能晚于 until

元数据更新可能会使现有记录在后续的增量收割中重新出现。OAI 标识符保持不变。

分页与恢复令牌 (Resumption Token)

ListRecordsListIdentifiers 每次响应最多返回 100 条记录

当有更多记录可用时,响应中包含 resumptionToken

<resumptionToken cursor="0">
eyJ2ZXJiIjoiTGlzdFJlY29yZHMi...
</resumptionToken>

在下一个请求中使用返回的令牌:

https://www.yourjournal.com/oai?verb=ListRecords&resumptionToken=eyJ2ZXJiIjoiTGlzdFJlY29yZHMi...

使用 resumptionToken 时:

  • 仅发送 verbresumptionToken
  • 请勿重复发送 metadataPrefixfromuntilset
  • 持续请求页面,直到不再返回 resumptionToken
  • 在一小时内使用该令牌。

令牌会保留原始请求中的存储库范围和所有筛选条件。

期刊集 (Sets)

期刊集仅在企业版 / 单出版社的出版社级存储库中可用。

列出所有期刊集:

https://www.publisher.com/oai?verb=ListSets

示例期刊集:

<set>
<setSpec>journal:nature-science</setSpec>
<setName>Nature Science</setName>
</set>

从出版社存储库收割一本期刊:

https://www.publisher.com/oai?verb=ListRecords&metadataPrefix=oai_dc&set=journal:nature-science

出版社级存储库返回的记录在其头部包含期刊集:

<header>
<identifier>oai:academic_stack:article:345</identifier>
<datestamp>2026-07-30T08:30:00Z</datestamp>
<setSpec>journal:nature-science</setSpec>
</header>

期刊级存储库不使用集。向期刊级存储库发送 ListSets 请求将返回 noSetHierarchy

已删除记录

存储库目前声明:

<deletedRecord>no</deletedRecord>

已删除或未发表的文章不会包含在 OAI 响应中,存储库也不暴露持久的已删除记录头。

收割工具应根据 OAI-PMH 的 deletedRecord=no 策略处理此存储库。

协议错误

无效请求会返回 OAI-PMH XML 错误,而非 JSON 或 HTML 应用程序错误。

常见错误代码包括:

错误代码含义
badVerb谓词缺失或不受支持。
badArgument必需参数缺失、格式错误或不允许使用。
cannotDisseminateFormat请求的元数据格式不受支持。
idDoesNotExist标识符在当前存储库中不存在。
noRecordsMatch没有记录匹配日期、集或存储库筛选条件。
noSetHierarchy期刊级存储库不支持集。
badResumptionToken令牌无效、已过期或属于另一个请求范围。

示例:

<error code="cannotDisseminateFormat">
Only oai_dc is supported.
</error>

推荐的收割工作流

对于首次全量收割:

  1. 发送 Identify
  2. 发送 ListMetadataFormats
  3. 如果使用出版社级存储库,发送 ListSets
  4. 使用 metadataPrefix=oai_dc 启动 ListRecords
  5. 追随每一个 resumptionToken,直到最后一页。
  6. 存储每条记录的 OAI 标识符和时间戳。

对于后续增量收割:

  1. 记录上一次成功收割的结束时间。
  2. 发送带有重叠 from 时间戳的 ListRecords,以避免遗漏边界附近的更新。
  3. 追随所有 resumptionToken 页面。
  4. 按 OAI 标识符更新现有记录。
  5. 保存新的成功收割时间。
使用较小的重叠区间

在计划增量收割时,在两次运行之间使用较小的重叠区间——例如,从上次成功收割时间前几分钟开始请求。OAI 标识符是稳定的,因此可以安全地按标识符更新重复结果。

常见问题排查

故障现象建议检查
noRecordsMatch确认期刊和文章处于公开状态,且日期范围使用 UTC 秒级时间戳。
cannotDisseminateFormat使用 metadataPrefix=oai_dc
badResumptionToken从原始请求重新开始收割;令牌在一小时后过期。
idDoesNotExist确认标识符属于当前期刊存储库,且文章保持公开。
noSetHierarchy仅在单出版社的出版社级 /oai 端点上使用集。
文章 URL 返回 404确认文章处于公开状态,且其卷、期和文章编号有效。
元数据更改不可见确认编辑后已保存文章,然后使用更新的时间戳重复增量请求。

在向索引服务提交 OAI-PMH 端点之前,请验证 IdentifyListRecords、分页、文章 URL、作者、日期、DOI 值和期刊元数据。