2. PDB 数据库下载与批量获取蛋白质-配体复合物结构
做结构数据清洗,第一步总得先搞到数据吧?
PDB 数据库是这行的老本营。几乎所有人都在用,但你想想看,每次手动去网页上一个一个点下载,碰上几百个结构怎么弄?
我刚开始做虚拟筛选时,就吃过这个亏。一个项目涉及 50 多个激酶结构,我手动下了整整两天,眼睛都快瞎了。后来发现,其实只要把流程梳理清楚,批量获取完全可以脚本化。
这一章,我把完整套路拆给你看。
2.1 PDB 数据库简介与访问方式
PDB(Protein Data Bank)目前由 wwPDB 联合管理,主站点在 rcsb.org。存储了超过 20 万个实验解析的生物大分子结构,包括 X 射线、冷冻电镜和核磁共振数据。
我个人习惯的访问方式有这几种:
- 网页交互搜索:适合查几个结构,快速预览。
- RESTful API:通过 URL 直接查询和下载,适合写脚本。
- FTP 批量镜像:整个数据库定期同步,适合搭建内部库。
- Python 库:比如 Biopython、pypdb,封装了 API 调用。
做批量获取,我基本只用后面三种。尤其是 API,写个循环就能解决大部分问题。
2.2 理解 RCSB 的高级搜索与表格
RCSB 的高级搜索支持布尔逻辑、属性过滤、序列相似性匹配等。
比如你要找所有含 ATP 类似物的激酶结构,就可以用这样的查询条件:
Query:
- 实验方法: X-RAY DIFFRACTION
- 分辨率: ≤ 2.5 Å
- 配体 ID: ATP (或类似物如 ANP)
- 链类型: Protein
- 来源: Homo sapiens
搜索结果展示为表格,但我建议你直接导出为 CSV。为什么?因为后续批量处理需要结构列表,吃 CSV 最省事。
我曾经有个项目需要批量处理 1200 个 GPCR 结构。如果手动点开每一个 PDB 页面去人工甄别,至少需要一整天。后来我写了段脚本,直接从 CSV 读取 PDB ID,五分钟搞定下载和初步过滤。这才是效率。
导出的 CSV 通常包含这些核心字段,你心里要有数:
| 字段名 | 说明 | 是否必备 |
|---|---|---|
| structureId | 4 位 PDB ID | 是 |
| title | 结构标题 | 参考 |
| resolution | 分辨率 (Å) | 强烈建议 |
| depositionDate | 提交日期 | 否 |
| ligandIds | 配体 ID 列表 | 是 |
| experimentalMethod | 实验方法 | 参考 |
2.3 批量下载方法:三种主流方式对比
说到批量下载,方法其实就那么几种。我按实际使用频率排序给你列出来。
2.3.1 方式一:使用 wget 直接拉取 (最常用)
PDB 提供了固定的 URL 结构,只要你有 ID 列表,一个循环就能搞定。
我个人用 wget 比较多,稳定且容易控制重试。核心命令是这样:
# 单个结构下载示例
wget https://files.rcsb.org/download/4HHB.pdb.gz
# 批量下载:从 id_list.txt 读取每个 ID
while read pdb_id; do
wget https://files.rcsb.org/download/${pdb_id}.pdb.gz
sleep 0.5 # 避免请求过快被封
done < id_list.txt
下载下来的 .pdb.gz 压缩包,可以统一解压:
gunzip *.pdb.gz
2.3.2 方式二:使用 Python 的 requests + Biopython
这种方式更灵活,适合需要下载后立刻做初步解析的场景。
import requests
from Bio import PDB
pdb_ids = ['4HHB', '1AKE', '2CPK']
base_url = "https://files.rcsb.org/download/"
for pid in pdb_ids:
url = f"{base_url}{pid}.pdb"
response = requests.get(url, timeout=30)
if response.status_code == 200:
with open(f"{pid}.pdb", 'w') as f:
f.write(response.text)
print(f"{pid} 下载成功")
else:
print(f"{pid} 下载失败,状态码 {response.status_code}")
2.3.3 方式三:FTP 镜像(适合建本地库)
如果你在机构内部要用到大量结构数据,可以直接 rsync 整个 PDB 镜像。官方提供匿名 FTP 服务。
# 同步 PDB 格式的完整归档(数据量较大,约 100GB+)
rsync -rlpt -v -z --delete \
rsync.rcsb.org::ftp_data/structures/divided/pdb/ \
/local/pdb_mirror/pdb/
同步后的目录结构是按 PDB ID 的中间两位分目录的,比如 4HHB 放在 /pdb/hh/ 下。这一套我之前在实验室搭过一次,后续做分子对接时就不用每次都联网下载了。
2.4 数据校验:下载完了不等于能用
批量下载最怕什么?
最怕下载到一半网络断了,或者文件损坏了你没发现。
我在这里提供几个快速校验的方法。
- 检查文件大小:正常 PDB 文件通常在几百 KB 到数 MB 之间。如果下载下来只有几 KB,基本是坏文件。
- 检查文件头部:用 `head -1` 看第一行是否以 `HEADER` 开头。
- 检查原子记录数:用 Python 统计 ATOM 和 HETATM 行数。
一个简单的校验脚本:
import os
def validate_pdb(filepath):
"""快速检查 PDB 文件是否完整"""
with open(filepath, 'r') as f:
lines = f.readlines()
header = lines[0].startswith('HEADER')
has_atoms = any(line.startswith(('ATOM', 'HETATM')) for line in lines)
end = any(line.startswith('END') for line in lines)
return header and has_atoms and end
# 批量检查
pdb_dir = "./downloaded_pdbs/"
for fname in os.listdir(pdb_dir):
if fname.endswith(".pdb"):
valid = validate_pdb(os.path.join(pdb_dir, fname))
if not valid:
print(f"损坏文件: {fname}")
2.5 配体信息的初步提取与筛选
下载完结构,你得确认这个结构里到底有没有配体。不是所有结构都含小分子配体。
我最常用的方法是直接从 PDB 文件中抓取 HETATM 记录。配体通常由 3 字母的 HET ID 标识,比如 ATP、STI、IMD。
# 提取某个 PDB 文件中的配体 ID
grep "^HETATM" 4HHB.pdb | awk '{print $4}' | sort -u
如果想用 Python 做个系统化的预筛选,可以这样:
def extract_ligands(pdb_file):
"""从 PDB 文件中提取所有配体 ID"""
ligands = set()
with open(pdb_file, 'r') as f:
for line in f:
if line.startswith("HETATM"):
het_id = line[17:20].strip()
# 排除水分子和常见离子
if het_id not in ['HOH', 'NA', 'CL', 'MG', 'ZN', 'CA']:
ligands.add(het_id)
return ligands
# 示例调用
print(extract_ligands("4HHB.pdb"))
2.6 本章知识体系总览
下面这张图总结了从“检索目标”到“确认可用结构”的核心流程。我习惯把预处理前的下载阶段叫做“数据狩猎期”,这个阶段目标只有一个:拿到正确且完整的结构性文件。后面再谈清洗和分析。
2.7 常见问题与避坑指南
我总结了一下自己这些年踩过的坑,给你列出来。嗯,都是真金白银换来的。
我曾经有一次在服务器后台跑批量下载,第二天回来发现网络断了,只下了一半。从此我养成了一个习惯:每个下载脚本后都加文件大小校验。小于 100 KB 的直接标记重下。
同一个配体在不同 PDB 里可能用不同 ID。比如 ATP 类似物,有时候叫 ANP,有时候叫 ACP。如果你只搜索 ATP,可能会漏掉大量有效结构。建议用 KEGG 或者 ChEBI 把相似配体 ID 都列出来。
搭建 FTP 镜像时要注意同步频率。如果我用的是每周同步的数据,那么本周新发布的结构就下载不到。对于时效性要求高的项目,建议直接从 API 获取。
说到底,批量获取蛋白质-配体结构并不是什么高深的技术。只要你把规则定好,校验做足,整个流程完全可以自动化。我自己的工具箱里,常年保留着几套下载脚本和校验函数,换项目时只要改一改 PDB ID 列表就能复用。