0

0

如何高效并发处理嵌套结构的 API 请求(Python 多线程实践)

聖光之護

聖光之護

发布时间:2026-02-05 18:21:38

|

981人浏览过

|

来源于php中文网

原创

如何高效并发处理嵌套结构的 API 请求(Python 多线程实践)

本文教你使用 `concurrent.futures.threadpoolexecutor` 并发调用深层嵌套的 api(如逐个获取 award 详情),将串行耗时从数分钟降至数秒,兼顾代码简洁性与生产可用性。

在处理类似开放采购数据(如 Paraguay 公共合同 API)这类层级嵌套的 JSON 响应时,常见的串行请求模式——即外层遍历 records,内层遍历每个 compiledRelease.awards,再为每个 award.id 发起独立 HTTP 请求——极易成为性能瓶颈。尤其当总量达数百个 compiledRelease、单个 awards 数组含数十甚至上百条记录时,同步阻塞式调用会导致总耗时呈线性增长(例如 500 次请求 × 平均 1.2s = 超 10 分钟),而网络 I/O 实际占用 CPU 极少,大量时间浪费在等待响应上。

此时,多线程并发是 Python 中最直接、稳定且无需修改业务逻辑的加速方案。concurrent.futures.ThreadPoolExecutor 正是为此类 I/O 密集型任务设计的标准库工具:它自动管理线程池、复用线程、支持结果收集与异常处理,且语法清晰易读。

以下是一个生产就绪的示例实现:

import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
import time

# 示例 API 调用函数(请替换为你的真实函数)
def api_call_function(award_id):
    # 注意:真实场景中应添加超时、重试、错误码判断
    try:
        response = requests.get(f"https://api.example.com/awards/{award_id}", timeout=10)
        response.raise_for_status()
        return response.json()
    except Exception as e:
        return {"error": str(e), "award_id": award_id}

# 主处理函数
def fetch_all_award_details(records, max_workers=20):
    """
    并发获取所有 awards 的完整详情
    :param records: 原始 JSON 中的 records 列表
    :param max_workers: 线程池最大并发数(建议 10–30,避免被限流)
    :return: 所有成功响应的列表(含 award_id 标识)
    """
    award_ids = []
    # 第一步:扁平化提取全部 award ID(保留上下文信息可选)
    for item in records:
        compiled = item.get("compiledRelease", {})
        awards = compiled.get("awards", [])
        for award in awards:
            award_id = award.get("id")
            if award_id:
                award_ids.append(award_id)

    print(f"共发现 {len(award_ids)} 个 award ID,启动并发请求...")

    results = []
    # 第二步:使用线程池并发执行
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        # 提交所有任务
        future_to_id = {executor.submit(api_call_function, aid): aid for aid in award_ids}

        # 按完成顺序收集结果(非提交顺序)
        for future in as_completed(future_to_id):
            award_id = future_to_id[future]
            try:
                data = future.result()
                results.append({"award_id": award_id, "data": data})
            except Exception as exc:
                results.append({"award_id": award_id, "error": str(exc)})

    return results

# 使用示例
if __name__ == "__main__":
    # 假设你已通过 requests 获取原始 records
    # response = requests.get("https://api.example.com/records?limit=100")
    # records = response.json().get("records", [])

    # 这里用模拟数据演示结构
    sample_records = [
        {
            "compiledRelease": {
                "awards": [
                    {"id": "award-001"},
                    {"id": "award-002"}
                ]
            }
        },
        {
            "compiledRelease": {
                "awards": [
                    {"id": "award-003"},
                    {"id": "award-004"},
                    {"id": "award-005"}
                ]
            }
        }
    ]

    start_time = time.time()
    all_details = fetch_all_award_details(sample_records, max_workers=10)
    end_time = time.time()

    print(f"\n✅ 完成!共获取 {len(all_details)} 条响应,耗时 {end_time - start_time:.2f} 秒")
    # 可进一步处理:筛选成功项、写入文件、入库等

? 关键注意事项与最佳实践:

秘塔写作猫
秘塔写作猫

秘塔写作猫是一个集AI写作、校对、润色、配图等为一体的创作平台

下载

立即学习Python免费学习笔记(深入)”;

  • 合理设置 max_workers:通常 10–30 是安全起点;过高可能触发服务端限流或本地端口耗尽;可通过小规模测试(如 50 个 ID)对比不同值的吞吐量来调优。
  • 务必添加超时与异常处理:HTTP 请求必须设 timeout(推荐 5–15 秒),否则单个失败请求会阻塞整个线程;as_completed() 确保不因某次失败中断整体流程。
  • 避免全局共享状态:线程间不要直接修改同一字典/列表;本例中每个 future.result() 返回独立数据,天然线程安全。
  • 替代方案说明:虽 asyncio + aiohttp 在理论吞吐上更高,但需全面重构为异步风格(包括 HTTP 客户端、JSON 解析等),学习成本与维护复杂度显著上升;对绝大多数 API 场景,ThreadPoolExecutor 已足够高效且稳健。

通过以上改造,你的脚本可在数秒内完成原本需数分钟的批量请求,同时保持代码逻辑清晰、易于调试和扩展。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

427

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

541

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

313

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

78

2025.09.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

589

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

279

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

21

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

23

2026.01.21

java连接字符串方法汇总
java连接字符串方法汇总

本专题整合了java连接字符串教程合集,阅读专题下面的文章了解更多详细操作。

6

2026.02.05

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 3.9万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号