如何编程获取UniProt查询全量TSV结果(解决仅返回25条问题)
问题原因
你当前仅拿到25条结果是UniProt REST API的默认分页规则导致的:接口默认单页返回25条记录,单次请求最大支持返回500条,必须通过分页遍历才能拉取全量结果。你当前使用的查询条件默认就会同时覆盖Swiss-Prot(已审阅)、TrEMBL(未审阅)两个库的所有数据,不需要额外加库筛选参数。
实现方案
直接通过解析接口响应头中返回的下一页地址做循环拉取即可,不需要手动计算总页数、拼接分页参数,稳定性最高。可直接使用以下修改后的代码:
import requests import sys import re import time WEBSITE_API = "https://rest.uniprot.org" def get_url(url, **kwargs): response = requests.get(url, **kwargs) if not response.ok: print(response.text) response.raise_for_status() sys.exit() return response # 初始化请求地址,size设为单页最大值500减少请求次数,指定返回TSV格式 next_url = f"{WEBSITE_API}/uniprotkb/search?query=length%3A%5B100%20TO%20109%5D&fields=id,accession,length,sequence&size=500" all_content = [] is_first_page = True while next_url: r = get_url(next_url, headers={"Accept": "text/plain; format=tsv"}) resp_text = r.text if is_first_page: # 第一页保留表头 all_content.append(resp_text) is_first_page = False else: # 后续页跳过第一行表头,只追加数据行 content_lines = resp_text.splitlines(keepends=True) all_content.extend(content_lines[1:]) # 从响应头解析下一页地址 next_url = None if "link" in r.headers: match = re.search(r'<([^>]+)>;\s*rel="next"', r.headers["link"]) if match: next_url = match.group(1) # 结果量大时可打开下方注释,加间隔避免触发频率限制 # time.sleep(1) # 全量结果写入文件 with open("request.txt", "w", encoding="utf-8") as file: file.writelines(all_content)
注意事项
- 单页
size参数最大不要超过500,否则接口会直接返回参数错误 - 优先使用响应头返回的下一页链接翻页,不要手动拼接
offset参数翻页,避免出现数据重复、遗漏的问题 - 如果查询区间对应的结果量较大(百万级以上),可以打开代码中注释的休眠逻辑,加1秒左右的请求间隔,避免触发接口频率限制
- 如果需要明确限定只查两个库、排除其他冗余数据源,可以将query参数替换为
query=(length:[100 TO 109]) AND (reviewed:true OR reviewed:false),和默认查询范围一致。
内容的提问来源于stack exchange,提问作者Tereza Neuwirthová
相关产品推荐
相关产品推荐

