<!-- markdown -->
## 1. 引言
Crossref REST API 是一个开放的学术元数据服务平台,为全球研究社区提供DOI(数字对象标识符)相关的元数据服务。本指南详细说明如何利用Crossref API开发论文检索工具,涵盖API基础、核心功能、最佳实践及实现细节。
### 1.1 数据来源与覆盖范围
- **数据来源**:
- Crossref成员组织(学术出版机构)提交的元数据
- 自动匹配过程(识别文献间的引用关系)
- 受信任的第三方来源(如Retraction Watch)
- **数据覆盖**:
- 学术出版物、基金、期刊等学术对象的元数据
- 不包含全文内容,仅提供文献的元数据和访问链接
- 每日更新引用统计信息,元数据通常在成员提交后20分钟内可用
> ⚠️ 注意:Crossref不从网站爬取数据或从其他聚合器获取数据,因此某些字段可能缺失。
---
## 2. 核心端点详解
### 2.1 Works端点(核心论文检索)
`https://api.crossref.org/works` 是论文检索的核心端点,支持多种查询方式:
#### 2.1.1 单个记录查询
通过DOI获取单篇论文的完整元数据:
```bash
https://api.crossref.org/works/10.1000/xyz123
```
- **HTTP HEAD请求**:快速检查DOI是否存在(无响应体,仅返回状态码)
```bash
curl --head "https://api.crossref.org/works/10.1000/xyz123"
```
#### 2.1.2 过滤查询
使用`filter`参数筛选特定条件的论文:
```bash
# 2020年发表的期刊文章
https://api.crossref.org/works?filter=type:journal-article,from-pub-date:2020-01-01,until-pub-date:2020-12-31
# 指定ISSN的期刊文章
https://api.crossref.org/works?filter=issn:2050-084X
# 开放获取(CC-BY许可证)
https://api.crossref.org/works?filter=license:CC-BY
```
#### 2.1.3 关键词搜索
使用`query`参数进行全文检索(**结果不按相关性排序**):
```bash
# 搜索包含"artificial intelligence"的标题/摘要
https://api.crossref.org/works?query=artificial+intelligence
# 搜索特定作者
https://api.crossref.org/works?query=author:"John Smith"
```
#### 2.1.4 分页处理
通过`cursor`参数实现大数据量分页:
```bash
# 第一页(必须带cursor=*)
https://api.crossref.org/works?query=AI&cursor=*&rows=100
# 第二页(使用上页返回的next-cursor)
https://api.crossref.org/works?query=AI&cursor=ABC123&rows=100
```
- **关键规则**:
- 每页最大1000条记录(`rows`参数)
- 当返回结果数量 < `rows`时,表示已到末页
- Cursor有效期5分钟
#### 2.1.5 统计摘要
使用`facet`参数获取统计信息:
```bash
# 获取2020年各类型论文数量统计(前10)
https://api.crossref.org/works?filter=from-pub-date:2020-01-01&facet=type-name:10
# 获取所有类型的统计
https://api.crossref.org/works?facet=type-name:*
```
### 2.2 其他相关端点
| 端点 | 用途 | 示例 |
|------|------|------|
| `funders` | 基金信息查询 | `https://api.crossref.org/funders?filter=location:Switzerland` |
| `journals` | 期刊信息查询 | `https://api.crossref.org/journals/2050-084X` |
| `members` | 出版机构查询 | `https://api.crossref.org/members?query=association+library` |
| `prefixes` | DOI前缀查询 | `https://api.crossref.org/prefixes/10.1000` |
---
## 3. 请求参数详解
| 参数 | 类型 | 说明 | 示例 |
|------|------|------|------|
| `filter` | string | 字段过滤条件(逗号分隔) | `type:journal-article,from-pub-date:2020-01-01` |
| `query` | string | 全文搜索关键词 | `query=climate+change` |
| `rows` | integer | 每页返回数量(默认20,最大1000) | `rows=100` |
| `cursor` | string | 分页游标(首次用`*`) | `cursor=*` |
| `sort` | string | 排序字段(如`created`、`deposited`) | `sort=created&order=desc` |
| `facet` | string | 统计字段(格式`field:count`) | `facet=type-name:10` |
### 3.1 过滤参数详解
- **日期范围**:`from-pub-date:YYYY-MM-DD,until-pub-date:YYYY-MM-DD`
- **文献类型**:`type:journal-article`, `type:book-chapter`等
- **许可协议**:`license:CC-BY`, `license:CC-BY-NC`
- **ISSN/ISBN**:`issn:2050-084X`, `isbn:978-3-16-148410-0`
- **机构ID**:`funder:100000001`
---
## 4. 响应结构解析
### 4.1 基础结构
```json
{
"status": "ok",
"message-type": "work-list",
"message": {
"items": [
{
"DOI": "10.1000/xyz123",
"title": ["Deep Learning for Natural Language Processing"],
"author": [
{"given": "John", "family": "Smith", "affiliation": [{"name": "MIT"}]},
{"given": "Jane", "family": "Doe", "affiliation": [{"name": "Stanford"}]}
],
"published-print": {"date-parts": [[2020, 1, 15]]},
"link": [
{
"URL": "https://doi.org/10.1000/xyz123",
"content-type": "text/html",
"content-version": "vor"
}
],
"reference-count": 45,
"is-referenced-by-count": 120,
"container-title": ["Journal of AI Research"],
"issn": ["2050-084X"],
"license": [{"URL": "https://creativecommons.org/licenses/by/4.0/"}]
}
],
"total-results": 1500,
"next-cursor": "ABC123"
}
}
```
### 4.2 关键字段说明
| 字段 | 说明 |
|------|------|
| `DOI` | 文献唯一标识符 |
| `title` | 文章标题列表(通常单元素数组) |
| `author` | 作者信息数组(含姓名、机构) |
| `published-print` | 实际出版日期(date-parts格式:[[年,月,日]]) |
| `link` | 访问链接(含URL和内容类型) |
| `reference-count` | 该文献引用的参考文献数量 |
| `is-referenced-by-count` | 被其他文献引用的次数 |
| `container-title` | 期刊/会议名称 |
| `issn` | 期刊ISSN号 |
| `license` | 开放获取许可协议信息 |
> 💡 **注意**:摘要(abstract)受版权保护,通常不可用;全文内容需通过`link`字段的URL访问。
---
## 5. 最佳实践与注意事项
### 5.1 用户标识与速率控制
- **必须设置**:
- `User-Agent`头:包含工具名称和开发者联系方式
- `mailto`参数:在URL中添加`mailto=your@email.com`
```bash
curl -H "User-Agent: MyResearchTool/1.0 (https://mytool.com; mailto:dev@mytool.com)" \
"https://api.crossref.org/works?query=AI&mailto=dev@mytool.com"
```
- **速率限制**:
| 池类型 | 请求速率 | 并发限制 |
|--------|----------|----------|
| Public | 50 req/sec | 5 concurrent |
| Polite | 50 req/sec | 5 concurrent |
| Plus | 150 req/sec | 15 concurrent |
- **错误处理**:
- `429 Too Many Requests`:立即暂停并指数退避重试
- `404 Not Found`:DOI不存在或来自其他注册机构
- `500 Server Error`:重试或联系Crossref支持
### 5.2 数据缓存策略
- 元数据更新延迟约20分钟,建议缓存时间≤30分钟
- 引用统计每日更新,缓存时间可设为24小时
- 对高频查询的DOI使用本地缓存(如Redis)
### 5.3 别名DOI处理
- 当查询的DOI是别名时,API会自动重定向到主DOI
- 检查响应中的`alias`字段确认别名关系
```json
{
"message": {
"alias": ["10.1000/old-doi"],
"DOI": "10.1000/new-doi"
}
}
```
---
## 6. 示例代码(Python)
### 6.1 基础查询
```python
import requests
def query_crossref(query, rows=100):
url = "https://api.crossref.org/works"
params = {
"query": query,
"rows": rows,
"mailto": "your@email.com"
}
headers = {
"User-Agent": "MyResearchTool/1.0 (https://mytool.com; mailto:your@email.com)"
}
response = requests.get(url, params=params, headers=headers)
response.raise_for_status()
return response.json()
# 示例:搜索"machine learning"相关论文
results = query_crossref("machine learning")
for item in results["message"]["items"]:
print(f"Title: {item['title'][0]}")
print(f"DOI: {item['DOI']}")
print(f"Published: {item['published-print']['date-parts'][0]}")
print("---")
```
### 6.2 分页处理
```python
def fetch_all_results(query, max_results=1000):
all_items = []
cursor = "*"
rows = 100
while len(all_items) < max_results:
params = {
"query": query,
"cursor": cursor,
"rows": min(rows, max_results - len(all_items)),
"mailto": "your@email.com"
}
headers = {"User-Agent": "MyResearchTool/1.0"}
response = requests.get("https://api.crossref.org/works",
params=params, headers=headers)
data = response.json()
items = data["message"]["items"]
all_items.extend(items)
if not items or len(items) < rows:
break
cursor = data["message"]["next-cursor"]
return all_items
```
---
## 7. 常见问题解答
### Q1: 如何判断DOI是否属于Crossref?
- 使用DOI基金会API检查注册机构:
```bash
curl https://doi.org/ra/10.1000 # 返回注册机构名称
```
- Crossref DOI前缀示例:`10.1000`, `10.1038`, `10.1109`
### Q2: 为什么查询结果不按相关性排序?
- Crossref API默认不按相关性排序,需使用`sort`参数指定排序字段(如`sort=score`)
### Q3: 如何处理跨页数据?
- 使用`cursor=*`开始,每次请求用上页返回的`next-cursor`
- 当返回结果数 < 请求的`rows`时,表示已获取所有数据
### Q4: 如何获取引用数据?
- 通过`is-referenced-by-count`字段获取被引次数
- 引用列表需通过其他服务获取(Crossref不提供完整引用列表)
### Q5: 为什么某些字段为空?
- 数据由成员提交,部分机构可能未提供完整元数据
- 摘要、参考文献等字段受版权保护可能不可用
---
## 8. 附录:参数速查表
### 8.1 支持的过滤字段
| 字段 | 说明 |
|------|------|
| `type` | 文献类型(journal-article, book-chapter等) |
| `from-pub-date` | 出版日期下限(YYYY-MM-DD) |
| `until-pub-date` | 出版日期上限(YYYY-MM-DD) |
| `issn` | 期刊ISSN号 |
| `funder` | 基金机构ID |
| `license` | 许可协议类型 |
| `member` | 出版机构ID |
### 8.2 常见HTTP状态码
| 状态码 | 含义 | 处理建议 |
|--------|------|----------|
| 200 | 成功 | 正常处理响应 |
| 404 | 不存在 | 检查DOI是否属于Crossref |
| 429 | 请求过多 | 按指数退避重试 |
| 500 | 服务器错误 | 重试或联系支持 |
---
> 📌 **重要提示**:Crossref API是开源学术基础设施的一部分,请遵守[使用规范](https://www.crossref.org/documentation/rest-api/),保持对服务的尊重。如有问题,请通过[Crossref社区论坛](https://community.crossref.org/)反馈。