关于 biorxiv-database
此技能介绍如何以编程方式访问 bioRxiv 和 medRxiv 预印本,适用于研究者及文献监测流程。其 REST API 可按 DOI 或日期范围获取元数据和版本信息,并查询发表状态。
主要功能
- 01按 DOI 或日期范围搜索预印本
- 02获取元数据、摘要和版本
- 03监测研究类别
- 04查询同行评审发表状态
- 05分页读取 API 结果
适用场景
- 01汇总每周特定类别的预印本
- 02筛查一组 DOI 对应的摘要
- 03跟踪预印本更新与版本
- 04核查哪些预印本已发表
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jaechang-hits/ sciagent-skills --skill biorxiv-database安装后在 Claude Code 中输入/biorxiv-database确认已加载。
详细介绍
bioRxiv / medRxiv 预印本数据库
概述
bioRxiv(生物学)和 medRxiv(健康科学)是免费的预印本服务平台,分别收录了 200,000+ 和 50,000+ 篇在同行评审前或评审期间发布的手稿。统一的 REST API 无需身份验证即可通过编程方式访问预印本元数据(标题、摘要、作者、类别、DOI、版本历史)。预印本以 PDF 格式提供,可通过 DOI、日期范围或类别检索。
适用场景
- 在发展迅速的领域中,在同行评审前查找最新研究(例如,疫情期间的传染病研究)
- 监控特定学科类别(例如,生物信息学、基因组学、神经科学)每周提交的预印本
- 检索一组 bioRxiv DOI 的元数据和摘要,用于文献筛选
- 构建预印本语料库,追踪预印本到正式发表的流程
- 检查特定预印本是否已更新或发表于同行评审期刊
- 对于经过同行评审的生物医学文献,请使用
pubmed-database;对于所有学科,请使用openalex-database
前提条件
- Python 包:
requests、pandas - 数据要求:bioRxiv/medRxiv DOI、日期范围或类别名称
- 环境:需要互联网连接;无需 API 密钥或身份验证
- 速率限制:未说明硬性限制;批量查询时请合理设置请求间隔
pip install requests pandas
快速入门
import requests
BASE = "https://api.biorxiv.org"
# Retrieve recent bioinformatics preprints
r = requests.get(f"{BASE}/details/biorxiv/2024-01-01/2024-01-07/0",
params={"category": "bioinformatics"})
r.raise_for_status()
data = r.json()
print(f"Total preprints: {int(data['messages'][0]['total'])}") # API returns total as a string
for article in data["collection"][:3]:
print(f"\n{article['title'][:80]}")
print(f" Authors : {article['authors'][:60]}")
print(f" DOI : {article['doi']}")
print(f" Category: {article['category']}")
核心 API
查询 1:按日期范围列出预印本
检索在某个日期范围内发布的所有预印本,也可以按类别筛选。
import requests, pandas as pd
BASE = "https://api.biorxiv.org"
def get_preprints(server, date_from, date_to, cursor=0, category=None):
"""
server: 'biorxiv' or 'medrxiv'
date_from, date_to: 'YYYY-MM-DD' strings
cursor: page offset (increments of 100)
"""
url = f"{BASE}/details/{server}/{date_from}/{date_to}/{cursor}"
r = requests.get(url)
r.raise_for_status()
return r.json()
data = get_preprints("biorxiv", "2024-01-01", "2024-01-03")
total = int(data["messages"][0]["total"]) # API returns total as a string — cast for arithmetic
print(f"bioRxiv preprints Jan 1-3, 2024: {total}")
rows = []
for article in data["collection"][:10]:
rows.append({
"doi": article["doi"],
"title": article["title"],
"authors": article["authors"][:80],
"category": article["category"],
"date": article["date"],
"version": article["version"],
})
df = pd.DataFrame(rows)
print(df[["title", "category", "date"]].head())
# Paginate through all results for a date range
def get_all_preprints(server, date_from, date_to, max_results=500):
all_articles = []
cursor = 0
while len(all_articles) < max_results:
data = get_preprints(server, date_from, date_to, cursor)
collection = data["collection"]
if not collection:
break
all_articles.extend(collection)
total = int(data["messages"][0]["total"]) # cast: API returns total as string
cursor += 100
if cursor >= total:
break
return all_articles[:max_results]
articles = get_all_preprints("biorxiv", "2024-01-01", "2024-01-07")
print(f"Retrieved {len(articles)} preprints from first week of 2024")
查询 2:按 DOI 获取预印本详情
按 DOI 检索特定预印本的完整元数据和版本历史。
import requests
BASE = "https://api.biorxiv.org"
# Retrieve specific preprint by DOI
doi = "10.1101/2024.01.01.000001" # Replace with real DOI
def get_by_doi(server, doi):
r = requests.get(f"{BASE}/details/{server}/{doi}")
r.raise_for_status()
return r.json()
# Generic example using bioRxiv DOI pattern
r = requests.get(f"{BASE}/details/biorxiv/10.1101/2024.05.28.596311")
if r.ok:
data = r.json()
articles = data.get("collection", [])
if articles:
art = articles[-1] # Latest version
print(f"Title : {art['title']}")
print(f"Authors : {art['authors'][:100]}")
print(f"Category: {art['category']}")
print(f"Date : {art['date']}")
print(f"Version : {art['version']}")
print(f"DOI : {art['doi']}")
print(f"Abstract (first 300): {art['abstract'][:300]}")
查询 3:查询已发表的预印本
检查预印本是否已发表于同行评审期刊。
import requests
BASE = "https://api.biorxiv.org"
def check_published(server, doi):
"""Check if a preprint DOI has a corresponding published article."""
r = requests.get(f"{BASE}/publisher/{server}/{doi}")
r.raise_for_status()
data = r.json()
return data.get("collection", [])
# Check one known preprint
doi = "10.1101/2024.05.28.596311"
published = check_published("biorxiv", doi)
if published:
pub = published[0]
print(f"Published in: {pub.get('published_journal')}")
print(f"Published DOI: {pub.get('published_doi')}")
else:
print(f"Preprint {doi} has not been published yet (or not tracked)")
查询 4:按类别监控
按特定研究类别监控预印本。
import requests, pandas as pd
from datetime import date, timedelta
BASE = "https://api.biorxiv.org"
# bioRxiv categories include: bioinformatics, genomics, neuroscience,
# immunology, cell-biology, biochemistry, microbiology, etc.
def weekly_category_digest(category, days_back=7):
"""Get preprints from last N days for a specific category."""
today = date.today()
date_from = (today - timedelta(days=days_back)).strftime("%Y-%m-%d")
date_to = today.strftime("%Y-%m-%d")
all_articles = []
cursor = 0
while True:
r = requests.get(f"{BASE}/details/biorxiv/{date_from}/{date_to}/{cursor}")
data = r.json()
batch = [a for a in data["collection"] if category.lower() in a["category"].lower()]
all_articles.extend(batch)
if len(data["collection"]) < 100:
break
cursor += 100
return pd.DataFrame(all_articles)[["doi", "title", "authors", "date"]] if all_articles else pd.DataFrame()
df = weekly_category_digest("genomics", days_back=3)
print(f"Recent genomics preprints: {len(df)}")
print(df[["title", "date"]].head())
查询 5:medRxiv 临床/健康研究
查询 medRxiv 上的健康和临床科学预印本。
import requests, pandas as pd
BASE = "https://api.biorxiv.org"
# medRxiv categories: infectious diseases, epidemiology, oncology,
# cardiology, neurology, psychiatry, public and global health, etc.
r = requests.get(f"{BASE}/details/medrxiv/2024-01-01/2024-01-07/0")
r.raise_for_status()
data = r.json()
total = int(data["messages"][0]["total"]) # cast: API returns total as string
print(f"medRxiv preprints Jan 1-7, 2024: {total}")
# Group by category
from collections import Counter
category_counts = Counter(a["category"] for a in data["collection"])
print("\nTop categories:")
for cat, count in category_counts.most_common(5):
print(f" {cat}: {count}")
查询 6:批量解析 DOI 并提取摘要
检索一组 bioRxiv DOI 对应的摘要。
import requests, time, pandas as pd
BASE = "https://api.biorxiv.org"
dois = [
"10.1101/2024.05.28.596311",
"10.1101/2023.11.28.569048",
"10.1101/2023.03.07.531523",
]
rows = []
for doi in dois:
r = requests.get(f"{BASE}/details/biorxiv/{doi}")
if r.ok:
collection = r.json().get("collection", [])
if collection:
art = collection[-1] # Latest version
rows.append({
"doi": doi,
"title": art.get("title"),
"category": art.get("category"),
"date": art.get("date"),
"abstract": art.get("abstract", "")[:300],
})
time.sleep(0.2)
df = pd.DataFrame(rows)
if not df.empty:
df.to_csv("preprint_abstracts.csv", index=False)
print(df[["doi", "title", "category"]].to_string(index=False))
else:
print("No valid preprints found for provided DOIs")
关键概念
API 端点结构
bioRxiv API 遵循以下模式:https://api.biorxiv.org/details/{server}/{interval}/{cursor}
server:biorxiv或medrxivinterval:DOI(用于获取单条记录)或date_from/date_to(用于指定日期范围)cursor:分页偏移量(0、100、200…)
版本追踪
预印本可以更新;每次更新都会创建一个新版本(v1、v2、v3…)。API 按时间顺序返回所有版本;collection 中的最后一项始终是最新版本。
常见工作流
工作流 1:每周预印本摘要流水线
目标:自动收集目标类别中上周发布的预印本,并导出以供审阅。
import requests, time, pandas as pd
from datetime import date, timedelta
BASE = "https://api.biorxiv.org"
TARGET_CATEGORIES = ["bioinformatics", "genomics", "systems biology"]
DAYS_BACK = 7
today = date.today()
date_from = (today - timedelta(days=DAYS_BACK)).strftime("%Y-%m-%d")
date_to = today.strftime("%Y-%m-%d")
print(f"Fetching bioRxiv preprints from {date_from} to {date_to}")
all_articles = []
cursor = 0
while True:
r = requests.get(f"{BASE}/details/biorxiv/{date_from}/{date_to}/{cursor}")
r.raise_for_status()
data = r.json()
batch = data["collection"]
if not batch:
break
all_articles.extend(batch)
total = int(data["messages"][0]["total"]) # cast: API returns total as string
cursor += 100
if cursor >= total:
break
time.sleep(0.1)
# Filter by target categories
filtered = [a for a in all_articles
if any(cat in a.get("category", "").lower() for cat in TARGET_CATEGORIES)]
df = pd.DataFrame(filtered)[["doi", "title", "authors", "category", "date"]]
df = df.drop_duplicates(subset="doi") # Remove duplicate versions
output_file = f"biorxiv_digest_{date_to}.csv"
df.to_csv(output_file, index=False)
print(f"\nSaved {len(df)} preprints across {len(TARGET_CATEGORIES)} categories → {output_file}")
print(df[["title", "category", "date"]].head(5).to_string(index=False))
工作流 2:预印本到正式发表的追踪器
目标:对于一组预印本 DOI,检查哪些已发表,并检索发表详情。
import requests, time, pandas as pd
BASE = "https://api.biorxiv.org"
preprint_dois = [
"10.1101/2024.05.28.596311",
"10.1101/2023.11.28.569048",
]
results = []
for doi in preprint_dois:
# Get preprint metadata
r_meta = requests.get(f"{BASE}/details/biorxiv/{doi}")
meta = {}
if r_meta.ok and r_meta.json().get("collection"):
art = r_meta.json()["collection"][-1]
meta = {"title": art["title"], "category": art["category"],
"preprint_date": art["date"]}
# Check publication status
r_pub = requests.get(f"{BASE}/publisher/biorxiv/{doi}")
published = {}
if r_pub.ok and r_pub.json().get("collection"):
pub = r_pub.json()["collection"][0]
published = {"journal": pub.get("published_journal"),
"pub_doi": pub.get("published_doi")}
results.append({"preprint_doi": doi, **meta, **published})
time.sleep(0.25)
df = pd.DataFrame(results)
print(df.to_string(index=False))
df.to_csv("preprint_publication_status.csv", index=False)
关键参数
| 参数 | 模块 | 默认值 | 范围 / 选项 | 作用 |
|---|---|---|---|---|
server | URL 路径 | 必填 | "biorxiv"、"medrxiv" | 选择预印本服务平台 |
date_from | URL 路径 | 必填 | "YYYY-MM-DD" | 日期范围的起始日期 |
date_to | URL 路径 | 必填 | "YYYY-MM-DD" | 日期范围的结束日期 |
cursor | URL 路径 | 0 | 0、100、200… | 分页偏移量(每页 100 条) |
category | 筛选条件 | — | 例如,"bioinformatics" | 按类别名称子字符串匹配(后置筛选) |
version | — | 所有版本 | — | API 返回所有版本;使用 [-1] 获取最新版本 |
最佳实践
-
始终使用最后一个元素获取最新版本:
collection数组按版本从旧到新排序。使用collection[-1]获取预印本的最新版本。 -
按类别进行后置筛选:API 不支持原生按类别筛选;请获取指定日期范围内的所有预印本,然后在客户端使用
if category in article["category"].lower()进行筛选。 -
尊重服务端资源:单独查询 DOI 时,每次查询之间添加
time.sleep(0.2);避免向 API 发送大量请求。 -
与 PubMed 交叉核对:
publisher端点会显示预印本的发表时间;使用pubmed-database获取经过同行评审的完整文章元数据。 -
处理缺失的摘要:有些预印本的
abstract字段为空。请始终使用art.get("abstract", "") or "No abstract available"进行保护。
常见操作示例
操作示例:下载预印本 PDF(适应 Cloudflare)
适用场景:获取 bioRxiv 预印本的全文 PDF。注意:截至 2026 年,www.biorxiv.org 前置了 Cloudflare 反机器人验证机制——即使使用 Session 并预先访问着陆页,直接调用 requests.get(..., headers={"User-Agent": "Mozilla/5.0"}) 也会持续返回 HTTP 403(“Just a moment...”)。以下模式会先尝试使用逼真的浏览器标头尽力下载;如果被拦截,则回退到 EuropePMC 获取元数据。
import requests
def download_biorxiv_pdf(doi, out_path=None):
"""Best-effort PDF download. If Cloudflare blocks, return False so the caller
can fall back to EuropePMC metadata or open the landing page in a browser."""
pdf_url = f"https://www.biorxiv.org/content/{doi}.full.pdf"
s = requests.Session()
s.headers.update({
"User-Agent": ("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"),
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,application/pdf,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
})
# Warm up the landing page first (sometimes lets Cloudflare's "trust" cookie set)
s.get(f"https://www.biorxiv.org/content/{doi}v1", timeout=30)
r = s.get(pdf_url, timeout=60)
if r.ok and r.content.startswith(b"%PDF"):
out = out_path or f"{doi.replace('/', '_')}.pdf"
with open(out, "wb") as f:
f.write(r.content)
print(f"Downloaded {out} ({len(r.content)//1024} KB)")
return True
print(f"PDF blocked (HTTP {r.status_code}); falling back to metadata-only via EuropePMC")
return False
def europepmc_metadata(doi):
"""Fetch preprint metadata via EuropePMC when bioRxiv PDF is blocked.
EuropePMC indexes bioRxiv as source 'PPR' and exposes a stable landing URL."""
r = requests.get("https://www.ebi.ac.uk/europepmc/webservices/rest/search",
params={"query": f"DOI:{doi}", "format": "json"}, timeout=30)
r.raise_for_status()
hits = r.json().get("resultList", {}).get("result", [])
if not hits:
return None
h = hits[0]
return {
"source": h.get("source"), # 'PPR' for preprints
"epmc_id": h.get("id"), # e.g. 'PPR860608'
"title": h.get("title"),
"landing_url": f"https://europepmc.org/article/{h.get('source')}/{h.get('id')}",
}
doi = "10.1101/2024.05.28.596311"
if not download_biorxiv_pdf(doi):
meta = europepmc_metadata(doi)
print(f" EuropePMC landing: {meta['landing_url']}")
print(f" Title: {meta['title'][:80]}")
操作示例:按类别统计预印本数量
适用场景:分析指定时间范围内 bioRxiv 各类别预印本的分布情况。
import requests, pandas as pd
from collections import Counter
r = requests.get("https://api.biorxiv.org/details/biorxiv/2024-01-01/2024-01-07/0")
data = r.json()
total = int(data["messages"][0]["total"]) # cast: API returns total as a string
# Fetch all pages
all_articles = data["collection"]
for cursor in range(100, min(total, 1000), 100):
r2 = requests.get(f"https://api.biorxiv.org/details/biorxiv/2024-01-01/2024-01-07/{cursor}")
all_articles.extend(r2.json()["collection"])
counts = Counter(a["category"] for a in all_articles)
df = pd.DataFrame(counts.most_common(), columns=["category", "count"])
print(df.head(10).to_string(index=False))
操作示例:检查预印本是否已发表
适用场景:快速检查单篇预印本的发表情况。
import requests
doi = "10.1101/2024.05.28.596311"
r = requests.get(f"https://api.biorxiv.org/publisher/biorxiv/{doi}")
collection = r.json().get("collection", [])
if collection:
print(f"Published: {collection[0]['published_journal']} | DOI: {collection[0]['published_doi']}")
else:
print("Not published or not tracked")
故障排查
| 问题 | 原因 | 解决方案 |
|---|---|---|
collection 为空 | 未找到 DOI,或日期范围内没有结果 | 核实 DOI 格式(以 10.1101/ 开头);检查日期范围 |
| 结果中存在重复预印本 | 返回了多个版本 | 按 DOI 去重:df.drop_duplicates(subset='doi', keep='last') |
| 缺少摘要字段 | 有些预印本没有结构化摘要 | 使用 art.get("abstract", "") or "N/A" 进行保护 |
total 计数与检索数量不一致 | 分页期间新增了预印本 | 接受近似总数;预印本会持续添加 |
| PDF 下载被拦截(HTTP 403 “Just a moment...”) | www.biorxiv.org/.../*.full.pdf 上的 Cloudflare 反机器人机制(仅使用 Mozilla/5.0 UA 无法绕过,使用 Session 加预先访问着陆页也不行) | 尝试使用 Session 加预热的操作示例;如果仍被拦截,则回退到 EuropePMC(source=PPR)获取元数据,或在浏览器中从 bioRxiv 着陆页手动获取 PDF |
cursor >= total 始终不成立;循环无限运行 | data['messages'][0]['total'] 返回的是字符串(例如 '1119');int_cursor >= str_total 会引发 TypeError 或进行字典序比较 | 显式转换类型:在每个分页循环中使用 int(data["messages"][0]["total"]) |
特定 DOI 对应的 collection 为空 | 该 DOI 无法解析为真实预印本(例如伪造的占位符,如 2023.01.01.000001,或已过期/撤回的 DOI) | 先在 https://www.biorxiv.org/content/{doi}v1 上核实 DOI;日期范围列表中的近期 DOI 是最可靠的示例 |
| 大日期范围的分页速度较慢 | 预印本数量较多 | 在繁忙时段使用更短的时间窗口(3–7 天) |
相关技能
pubmed-database— 同行评审的生物医学文献,可用于核实预印本的已发表版本openalex-database— 范围更广的学术索引,索引延迟后也会收录 bioRxiv 内容literature-review— 将预印本纳入系统综述的指南scientific-brainstorming— 将预印本提醒用作生成假设的输入
参考资料
- bioRxiv API 文档 — 官方 API 端点和响应格式
- bioRxiv 关于页面 — 服务概览、投稿指南
- medRxiv 关于页面 — 健康科学预印本服务详情
- 预印本指南综述(Fraser 等,2021) — 研究中引用和使用预印本的最佳实践