如何用Asyncio异步获取DataFrame中28万+URL文件大小?
使用asyncio异步获取大量文件大小
要处理287000+个URL的文件大小获取,异步方案核心是用异步HTTP客户端(比如aiohttp)替代同步的urllib/requests,同时通过并发控制避免触发服务器限流。以下是完整实现:
步骤1:安装依赖
首先需要安装异步HTTP库:
pip install aiohttp
步骤2:异步实现代码
import pandas as pd import aiohttp import asyncio async def get_file_size(session: aiohttp.ClientSession, url: str, semaphore: asyncio.Semaphore): # 用信号量控制并发数,避免请求过多被服务器拦截 async with semaphore: try: # 发送HEAD请求,仅获取响应头,无需下载整个文件 async with session.head(url, timeout=aiohttp.ClientTimeout(total=10)) as response: # 从响应头获取文件大小(字节) size_bytes = int(response.headers.get('Content-Length', 0)) return size_bytes except Exception as e: # 处理异常:比如URL无效、超时、服务器错误等 print(f"处理URL {url}时出错: {str(e)}") return 0 async def main(): df1 = pd.read_csv("report.csv", sep=';', encoding='utf-8') # 替换为你的实际URL列,这里保留示例数据 df1['Gravação'] = [ 'https://www.pngall.com/wp-content/uploads/11/Harbor-Seal-PNG-Pic.png', 'https://www.pngall.com/wp-content/uploads/11/Harbor-Seal-PNG-File.png', 'https://www.pngall.com/wp-content/uploads/11/Harbor-Seal-PNG-Photo.png', 'https://www.pngall.com/wp-content/uploads/11/Harbor-Seal-PNG-Clipart.png' ] # 控制并发数:根据服务器承受能力调整,比如设为50 semaphore = asyncio.Semaphore(50) # 创建异步会话,复用连接池提升效率 async with aiohttp.ClientSession() as session: # 生成所有异步任务 tasks = [get_file_size(session, url, semaphore) for url in df1['Gravação']] # 并发执行所有任务,获取结果列表 tamanho_mb = await asyncio.gather(*tasks) # 可选:如果需要转成MB,直接处理列表 # tamanho_mb = [size / (1024*1024) for size in tamanho_mb] print(tamanho_mb) if __name__ == "__main__": # 运行异步主函数 asyncio.run(main())
关键说明
- HEAD请求:相比GET请求,HEAD只返回响应头,不需要下载文件内容,能大幅节省带宽和时间。
- 并发控制:用
asyncio.Semaphore限制同时发起的请求数,避免因请求量过大被服务器封禁或触发限流。建议根据目标服务器的实际情况调整(比如从30-100开始测试)。 - 异常处理:针对无效URL、超时、服务器错误等情况做了捕获,保证程序不会因单个请求失败而中断。
- 连接复用:
aiohttp.ClientSession会自动维护连接池,减少TCP握手开销,提升批量请求效率。
内容的提问来源于stack exchange,提问作者matheusppedroso
相关产品推荐
相关产品推荐

