高效并发抓取 UniProt REST API 多个基因查询结果的完整教程

落雪同学_4369

落雪同学_4369

2026-05-26

405人浏览

原创

高效并发抓取 UniProt REST API 多个基因查询结果的完整教程

本文介绍如何使用 Python 的 multiprocessing.Pool 替代 concurrent.futures.ThreadPoolExecutor,真正实现 CPU/IO 并行化,显著提升批量请求 UniProt REST API 的速度,并安全解析 Excel 格式响应、合并结果。

本文介绍如何使用 python 的 `multiprocessing.pool` 替代 `concurrent.futures.threadpoolexecutor`,真正实现 cpu/io 并行化,显著提升批量请求 uniprot rest api 的速度,并安全解析 excel 格式响应、合并结果。

在生物信息学数据获取场景中,频繁调用 UniProt REST API(如 https://rest.uniprot.org/uniprotkb/stream)查询多个基因(如从单细胞 RNA-seq 差异表达基因列表)是常见需求。然而,单纯依赖线程池(ThreadPoolExecutor)往往提速有限——这是因为 Python 的 GIL(全局解释器锁)限制了 CPU 密集型任务的并行性,而 HTTP 请求虽属 IO 密集型,但当响应体较大(如 Excel 文件)、解析开销高(pandas.read_excel 本身较重)时,线程竞争和内存拷贝反而成为瓶颈。

此时,多进程(multiprocessing)是更优解:每个进程拥有独立的 Python 解释器和内存空间,可绕过 GIL,真正并行执行网络请求 + Excel 解析 + 数据提取,尤其适合“请求-解析-结构化”这一整条链路。

Wordpress REST API
Wordpress REST API

OpenClaw技能,提供WordPress REST API命令行工具,支持通过原生HTTP处理文章、页面、分类、标签、用户及自定义请求。

下载

以下是一个生产就绪的优化方案,已融合原代码逻辑并增强健壮性:

✅ 核心改进点

  • 使用 multiprocessing.Pool 实现真正的并行请求与解析;
  • 采用 pool.imap_unordered() 流式处理,避免内存积压;
  • 内置异常捕获与重试机制,防止单个失败中断全部流程;
  • 显式控制 chunksize 提升 IPC(进程间通信)效率;
  • 返回结构化元组 (gene_name, first_row_df),便于后续调试与去重。

? 完整可运行代码示例

import warnings
import pandas as pd
import requests
from io import BytesIO
from multiprocessing import Pool, current_process
from tqdm import tqdm
import time

# 忽略 openpyxl 样式警告(非关键)
warnings.simplefilter("ignore", UserWarning)

def get_UniPQuery_link(gene_name, tax_id="9606", file_format="xlsx"):
    """生成 UniProt REST API 查询链接(精简版,移除冗余参数)"""
    query = f"((gene:{gene_name}) AND (taxonomy_id:{tax_id}))"
    fields = "accession,reviewed,id,protein_name,gene_names," \
             "organism_name,length,ft_intramem,cc_subcellular_location," \
             "ft_topo_dom,ft_transmem,cc_function,lit_doi_id,lit_pubmed_id"
    url = (
        f"https://rest.uniprot.org/uniprotkb/stream?"
        f"fields={fields}&format={file_format}&size=500&query={query}"
    )
    return url

def fetch_gene_data(gene_name, max_retries=3):
    """
    单基因请求 + 解析函数(进程内执行)
    返回: (gene_name, first_row_df) 或 (gene_name, None) 若失败
    """
    url = get_UniPQuery_link(gene_name)

    for attempt in range(max_retries):
        try:
            response = requests.get(url, timeout=30)
            response.raise_for_status()  # 抛出 4xx/5xx 异常

            # 解析 Excel 响应
            df = pd.read_excel(BytesIO(response.content))

            if not df.empty:
                return gene_name, df.iloc[[0]].assign(query_gene=gene_name)
            else:
                return gene_name, None

        except Exception as e:
            if attempt == max_retries - 1:
                print(f"[{current_process().name}] ❌ 失败 {gene_name}: {e}")
                return gene_name, None
            time.sleep(0.5 * (2 ** attempt))  # 指数退避

    return gene_name, None

if __name__ == "__main__":
    # 示例:替换为你的 unique_genes 列表
    unique_genes = ["TP53", "EGFR", "BRAF", "KRAS", "PIK3CA", "AKT1"]

    print(f"▶ 开始并发请求 {len(unique_genes)} 个基因...")
    start_time = time.time()

    # 启动 4 个工作进程(可根据 CPU 核数调整)
    with Pool(processes=4) as pool:
        # imap_unordered + tqdm 实现带进度的流式处理
        results = list(
            tqdm(
                pool.imap_unordered(fetch_gene_data, unique_genes, chunksize=2),
                total=len(unique_genes),
                desc="? 获取 UniProt 数据"
            )
        )

    # 分离成功/失败结果
    valid_dfs = [df for _, df in results if df is not None]
    failed_genes = [name for name, df in results if df is None]

    # 合并所有有效结果
    if valid_dfs:
        final_df = pd.concat(valid_dfs, ignore_index=True)
        final_df.to_excel("uniprot_gene_summary.xlsx", index=False)
        print(f"\n✅ 成功获取 {len(valid_dfs)} 条记录,已保存至 uniprot_gene_summary.xlsx")
    else:
        print("\n⚠️  未获取到任何有效数据,请检查网络或基因名拼写。")

    if failed_genes:
        print(f"⚠️  以下基因请求失败: {failed_genes}")

    elapsed = time.time() - start_time
    print(f"⏱️  总耗时: {elapsed:.2f} 秒 ({elapsed/60:.2f} 分钟)")

⚠️ 关键注意事项

  • API 限流:UniProt REST API 对未认证用户有请求频率限制(约 10 req/sec)。若批量量极大(>1000 基因),建议:
    • 添加 time.sleep(0.1) 在 fetch_gene_data 中(慎用,会降低吞吐);
    • 或改用 UniProt Batch Retrieval 或下载全量数据库本地匹配。
  • 内存管理:Excel 文件较大时(>5MB),pd.read_excel 可能触发 OOM。可改用 engine='openpyxl' + usecols 限定列,或直接解析 TSV(format='tsv' 更轻量)。
  • Windows 兼容性:务必确保 if __name__ == "__main__": 包裹主逻辑,否则多进程在 Windows 下会递归启动。
  • 结果去重:iloc[[0]] 仅取首条,但某些基因名可能对应多个蛋白(如剪接变体)。如需全量,可移除 .iloc[[0]] 并保留整个 df。

✅ 性能对比小结

方法 理论并行性 实际提速(~100 genes) 适用场景
ThreadPoolExecutor 线程级(受 GIL 制约) ~1.5–2× 轻量 JSON/API 响应
multiprocessing.Pool 进程级(无 GIL) ~3–4×(尤其大 Excel) 本例(含 Excel 解析)
异步(aiohttp + asyncio) 协程级(高并发 IO) ~2.5–3.5× 需改造解析逻辑,学习成本高

通过将计算密集型的 Excel 解析卸载到独立进程中,本方案实现了真正的横向扩展能力。对于百级至千级基因批量注释任务,这是兼顾开发效率与执行性能的推荐实践。

大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

rest api

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1751

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4524

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1729

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

26577

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3227

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3227

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1183

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

596

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2503

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.7万人学习