Files
2026-05-30 16:22:29 +08:00

8.1 KiB

API 使用指南

本文档详细说明如何使用三个主要 API 进行文献验证。

Semantic Scholar API

概述

Semantic Scholar 是一个免费的学术搜索引擎,提供强大的 API 用于论文检索和元数据获取。

优势:

  • 免费使用,无需 API key
  • 覆盖广泛的学科领域
  • 提供丰富的元数据
  • 支持模糊搜索

限制:

  • 请求频率限制:100 requests/5min
  • 部分论文可能缺失

API 端点

1. 通过 Paper ID 获取论文

GET https://api.semanticscholar.org/graph/v1/paper/{paper_id}

2. 搜索论文

GET https://api.semanticscholar.org/graph/v1/paper/search?query={query}

Python 示例

安装:

pip install semanticscholar

基本用法:

from semanticscholar import SemanticScholar

sch = SemanticScholar()

# 通过标题搜索
results = sch.search_paper("Attention is All You Need", limit=5)
for paper in results:
    print(f"Title: {paper.title}")
    print(f"Authors: {[a.name for a in paper.authors]}")
    print(f"Year: {paper.year}")
    print(f"DOI: {paper.externalIds.get('DOI', 'N/A')}")
    print("---")

通过 DOI 获取:

# DOI 格式: DOI:10.48550/arXiv.1706.03762
paper = sch.get_paper("DOI:10.48550/arXiv.1706.03762")
print(f"Title: {paper.title}")
print(f"Citations: {paper.citationCount}")

字段说明

返回的主要字段:

  • paperId - Semantic Scholar 内部 ID
  • title - 论文标题
  • authors - 作者列表
  • year - 发表年份
  • venue - 发表场所(会议/期刊)
  • externalIds - 外部标识符(DOI, arXiv, PubMed 等)
  • citationCount - 引用次数
  • abstract - 摘要

错误处理

try:
    paper = sch.get_paper("invalid_id")
except Exception as e:
    print(f"Error: {e}")
    # 处理错误:标记需要人工验证

arXiv API

概述

arXiv 是预印本论文库,提供免费的 API 用于访问论文元数据。

优势:

  • 完全免费,无需认证
  • 覆盖物理、数学、计算机科学等领域
  • 提供完整的论文 PDF
  • 更新及时

限制:

  • 仅限预印本论文
  • 不包含已发表的期刊版本信息

API 端点

查询接口:

GET http://export.arxiv.org/api/query?search_query={query}&start={start}&max_results={max}

Python 示例

安装:

pip install arxiv

基本用法:

import arxiv

# 通过 arXiv ID 获取
paper = next(arxiv.Search(id_list=["1706.03762"]).results())
print(f"Title: {paper.title}")
print(f"Authors: {[a.name for a in paper.authors]}")
print(f"Published: {paper.published}")
print(f"PDF URL: {paper.pdf_url}")

# 通过标题搜索
search = arxiv.Search(
    query="Attention is All You Need",
    max_results=5,
    sort_by=arxiv.SortCriterion.Relevance
)

for result in search.results():
    print(f"Title: {result.title}")
    print(f"arXiv ID: {result.entry_id.split('/')[-1]}")
    print("---")

arXiv ID 格式

识别 arXiv ID:

  • 新格式: YYMM.NNNNN (如 2301.12345)
  • 旧格式: arch-ive/YYMMNNN (如 cs/0703001)

从 URL 提取:

import re

def extract_arxiv_id(text):
    # 匹配新格式
    match = re.search(r'\d{4}\.\d{4,5}', text)
    if match:
        return match.group()
    # 匹配旧格式
    match = re.search(r'[a-z-]+/\d{7}', text)
    if match:
        return match.group()
    return None

CrossRef API

概述

CrossRef 是 DOI 注册机构,提供权威的学术文献元数据。

优势:

  • DOI 是最可靠的唯一标识符
  • 覆盖几乎所有正式发表的论文
  • 数据质量高,权威性强
  • 支持 BibTeX 格式直接获取

限制:

  • 仅限有 DOI 的论文
  • 预印本通常没有 DOI

API 端点

通过 DOI 获取元数据:

GET https://api.crossref.org/works/{doi}

通过 DOI 获取 BibTeX:

GET https://doi.org/{doi}
Headers: Accept: application/x-bibtex

Python 示例

通过 DOI 获取元数据:

import requests

def get_crossref_metadata(doi):
    url = f"https://api.crossref.org/works/{doi}"
    response = requests.get(url)
    if response.status_code == 200:
        data = response.json()
        return data['message']
    return None

# 示例
doi = "10.48550/arXiv.1706.03762"
metadata = get_crossref_metadata(doi)
if metadata:
    print(f"Title: {metadata['title'][0]}")
    print(f"Authors: {[f\"{a['given']} {a['family']}\" for a in metadata['author']]}")
    print(f"Published: {metadata['published']['date-parts'][0]}")

通过 DOI 获取 BibTeX:

def doi_to_bibtex(doi):
    url = f"https://doi.org/{doi}"
    headers = {"Accept": "application/x-bibtex"}
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        return response.text
    return None

# 示例
bibtex = doi_to_bibtex("10.48550/arXiv.1706.03762")
print(bibtex)

DOI 格式

标准格式:

  • 10.XXXX/suffix (如 10.1038/nature12345)
  • 前缀 10. 是固定的
  • 中间是注册机构代码
  • 后缀是出版商定义的

从文本中提取 DOI:

import re

def extract_doi(text):
    # 匹配 DOI 格式
    match = re.search(r'10\.\d{4,}/[^\s]+', text)
    if match:
        return match.group()
    return None

API 选择策略

根据引用信息选择最合适的 API:

决策流程

有 DOI?
  ├─ 是 → CrossRef API (最可靠)
  └─ 否 → 有 arXiv ID?
      ├─ 是 → arXiv API
      └─ 否 → Semantic Scholar API (通用搜索)

实现示例

def verify_citation(citation_info):
    """
    根据引用信息选择合适的 API 进行验证

    Args:
        citation_info: dict with keys: doi, arxiv_id, title, authors

    Returns:
        验证结果字典
    """
    # 策略 1: DOI 优先
    if citation_info.get('doi'):
        return verify_with_crossref(citation_info['doi'])

    # 策略 2: arXiv ID
    if citation_info.get('arxiv_id'):
        return verify_with_arxiv(citation_info['arxiv_id'])

    # 策略 3: 通用搜索
    if citation_info.get('title'):
        return verify_with_semantic_scholar(
            citation_info['title'],
            citation_info.get('authors')
        )

    return {'status': 'insufficient_info'}

最佳实践

1. 错误处理

import time
from requests.exceptions import RequestException

def api_call_with_retry(func, max_retries=3):
    """带重试的 API 调用"""
    for i in range(max_retries):
        try:
            return func()
        except RequestException as e:
            if i == max_retries - 1:
                raise
            time.sleep(2 ** i)  # 指数退避

2. 速率限制

import time

class RateLimiter:
    def __init__(self, calls_per_minute):
        self.calls_per_minute = calls_per_minute
        self.last_call = 0

    def wait_if_needed(self):
        elapsed = time.time() - self.last_call
        min_interval = 60.0 / self.calls_per_minute
        if elapsed < min_interval:
            time.sleep(min_interval - elapsed)
        self.last_call = time.time()

# 使用示例
limiter = RateLimiter(calls_per_minute=20)
limiter.wait_if_needed()
result = api_call()

3. 缓存结果

import json
from pathlib import Path

class APICache:
    def __init__(self, cache_dir=".cache"):
        self.cache_dir = Path(cache_dir)
        self.cache_dir.mkdir(exist_ok=True)

    def get(self, key):
        cache_file = self.cache_dir / f"{key}.json"
        if cache_file.exists():
            return json.loads(cache_file.read_text())
        return None

    def set(self, key, value):
        cache_file = self.cache_dir / f"{key}.json"
        cache_file.write_text(json.dumps(value))

总结

API 对比

API 优势 限制 推荐场景
CrossRef 最权威,支持 BibTeX 仅限有 DOI 的论文 有 DOI 时首选
arXiv 免费,更新快 仅限预印本 arXiv 论文
Semantic Scholar 覆盖广,模糊搜索 部分论文缺失 通用搜索

验证可靠性排序

  1. CrossRef (DOI) - 最可靠
  2. arXiv (arXiv ID) - 可靠
  3. Semantic Scholar (标题搜索) - 较可靠,需要人工确认