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

基于Requests的脚本中使用生成器优化性能的方法咨询

网络请求脚本优化:生成器的作用与实际提速方案

生成器能直接让脚本变快吗?

不能。你的脚本耗时超24小时,核心瓶颈是网络IO等待——每个GET请求都要等远程设备响应,这部分时间生成器帮不了你。生成器的优势是节省内存、延迟加载,适合处理超大URL列表(比如CSV有几十万条),避免一次性把所有URL加载到内存里导致内存溢出,但它不会减少网络请求的等待时间。

不过生成器可以和并发处理结合,让脚本的资源利用更高效,间接提升整体运行效率。

怎么把生成器用到你的脚本里?

先写一个生成器函数来读取CSV里的URL,代替一次性把所有URL读成列表:

import csv

def url_generator(csv_path):
    # 逐行读取CSV,每次只生成一个URL,内存占用极低
    with open(csv_path, 'r', encoding='utf-8') as f:
        reader = csv.reader(f)
        next(reader)  # 跳过表头(如果CSV有表头的话)
        for row in reader:
            # 假设URL在CSV的第一列,根据你的实际格式调整索引
            yield row[0].strip()

之后你就可以用for url in url_generator("your_urls.csv")来遍历所有URL,不用一次性加载全部数据到内存。

真正提速的关键:并发处理网络请求

既然瓶颈是网络等待,就要同时发送多个请求,用多线程或异步IO来利用等待时间做其他请求。下面是两种实用方案:

方案1:Requests + 线程池(简单易上手)

适合大多数场景,线程池专门处理IO密集型任务:

import requests
import concurrent.futures
import json

def fetch_and_save(url):
    try:
        # 发送请求,设置超时避免无限等待
        resp = requests.get(url, timeout=30)
        resp.raise_for_status()  # 捕获HTTP错误
        
        # 生成文件名,避免特殊字符问题
        filename = f"{url.replace('://', '_').replace('/', '_').replace(':', '')}.json"
        # 保存JSON(如果是XML,改成对应的解析和保存逻辑)
        with open(filename, 'w', encoding='utf-8') as f:
            json.dump(resp.json(), f, indent=2)
        print(f"Successfully saved: {url}")
    except Exception as e:
        print(f"Failed to fetch {url}: {str(e)}")

if __name__ == "__main__":
    csv_path = "your_urls.csv"
    # 用生成器提供URL
    url_gen = url_generator(csv_path)
    
    # 线程池大小:根据你的网络带宽和设备承受能力调整,建议20-50
    with concurrent.futures.ThreadPoolExecutor(max_workers=30) as executor:
        # 批量提交任务,生成器会逐个供给URL
        executor.map(fetch_and_save, url_gen)

方案2:Aiohttp异步IO(更高性能)

如果URL数量特别多,异步IO的效率比线程池更高:

import aiohttp
import asyncio
import csv
import json

async def fetch_and_save(session, url):
    try:
        async with session.get(url, timeout=30) as resp:
            resp.raise_for_status()
            data = await resp.json()
            
            filename = f"{url.replace('://', '_').replace('/', '_').replace(':', '')}.json"
            with open(filename, 'w', encoding='utf-8') as f:
                json.dump(data, f, indent=2)
            print(f"Successfully saved: {url}")
    except Exception as e:
        print(f"Failed to fetch {url}: {str(e)}")

async def main(csv_path):
    url_gen = url_generator(csv_path)
    # 创建异步会话
    async with aiohttp.ClientSession() as session:
        # 生成所有异步任务
        tasks = [fetch_and_save(session, url) for url in url_gen]
        # 等待所有任务完成
        await asyncio.gather(*tasks)

if __name__ == "__main__":
    csv_path = "your_urls.csv"
    asyncio.run(main(csv_path))

额外优化细节

  • 重试机制:给请求加重试,比如用tenacity库,避免因临时网络故障导致失败
  • 限流:如果设备有请求频率限制,要控制并发数或加延迟,避免被拉黑
  • 批量处理:如果设备API支持批量请求,尽量合并请求,减少总请求次数
  • 日志记录:把失败的URL记录到文件,方便后续重跑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 08:05:32