You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中并行调用不同的URL

把顺序HTTP请求改成并行执行的实现方案

嗨,我来帮你搞定这个并行请求的问题~首先得说一句:你提到的subprocess其实不太适合这个场景,它主要用来启动外部进程(比如跑另一个脚本或系统命令),而HTTP请求属于IO密集型任务,用线程池来并行处理会更高效也更简单。下面我结合你的现有代码,一步步给你实现:

核心思路

用concurrent.futures.ThreadPoolExecutor创建线程池,把每个URL的请求逻辑封装成独立函数,让线程池自动分配线程并行执行这些请求,最后统一收集结果。

完整代码示例

import requests
import time
import zipfile
import glob
import os
import re
import json
import csv
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor, as_completed

# 保留你原有的session和headers设置
session = requests.Session()
session.trust_env = False
headers = {'Authorization': 'Basic ...'}

# 定义单个URL的请求处理函数
def fetch_url(url):
    """处理单个URL的请求,返回响应结果或异常信息"""
    try:
        response = session.get(url, headers=headers)
        response.raise_for_status()  # 主动触发HTTP错误(比如4xx/5xx状态码)
        # 这里可以根据你的需求返回具体内容,比如响应文本、JSON等
        return {"url": url, "status": response.status_code, "content": response.text}
    except Exception as e:
        # 捕获请求过程中的异常,方便排查问题
        return {"url": url, "error": str(e)}

if __name__ == "__main__":
    # 准备你要请求的URL列表(替换成你的实际URL)
    target_urls = [
        "https://example.com/api/1",
        "https://example.com/api/2",
        "https://example.com/api/3",
        # ... 更多URL
    ]

    # 记录开始时间,对比并行和顺序的效率
    start_time = time.time()

    # 创建线程池,max_workers设置并行的线程数(根据目标网站限流情况调整,别太激进)
    with ThreadPoolExecutor(max_workers=10) as executor:
        # 提交所有URL请求到线程池,返回future对象与URL的映射
        future_to_url = {executor.submit(fetch_url, url): url for url in target_urls}
        
        # 遍历完成的future,收集并处理结果
        for future in as_completed(future_to_url):
            url = future_to_url[future]
            try:
                result = future.result()
                if "error" in result:
                    print(f"请求URL {url} 失败: {result['error']}")
                else:
                    print(f"请求URL {url} 成功,状态码: {result['status']}")
                    # 这里可以对响应内容做后续处理,比如保存到文件、解析JSON等
            except Exception as e:
                print(f"处理URL {url} 时发生意外错误: {str(e)}")

    # 输出总耗时
    print(f"并行请求总耗时: {time.time() - start_time:.2f}秒")

关键细节说明

  • 为什么用ThreadPoolExecutor?:HTTP请求大部分时间在等待服务器响应(IO操作),线程切换的开销远低于进程,所以线程池更适合这类场景;如果是CPU密集型任务才考虑用ProcessPoolExecutor。
  • Session的线程安全性:requests的Session对象是线程安全的(内部有锁机制),多个线程可以共用同一个Session,这样能复用TCP连接,大幅提升请求效率。
  • 异常处理:在fetch_url函数里加了try-except,能避免单个请求失败导致整个程序崩溃,还能记录错误信息方便排查。
  • max_workers的设置:别设置太大(比如不要超过20),否则可能触发目标网站的限流机制,导致请求被封禁,具体数值可以根据目标网站的并发限制调整。

对比顺序执行的优势

如果是顺序执行,每个请求都要等上一个完成才能开始,总耗时是所有请求耗时的总和;而并行执行的总耗时大概等于耗时最长的那个请求的时间,效率提升非常明显。

内容的提问来源于stack exchange,提问作者sdgd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:59:53