如何优化Python Requests批量URL检测代码以提升响应速度?
优化批量URL活跃性检测的Python代码
原代码采用同步串行方式发送HEAD请求,每个请求需等待前一个完成后才执行下一个,500+条URL的耗时会线性累加;同时逐行修改DataFrame的操作也存在效率损耗。以下是两种高效优化方案:
方案一:异步请求(IO密集场景最优)
使用aiohttp实现异步并发请求,同时发起多个HTTP请求,大幅压缩等待时间。
import aiohttp import asyncio import pandas as pd async def check_url(session, url): try: async with session.head(url, allow_redirects=False, timeout=5) as response: return 'active' if response.status == 200 else 'false' except Exception: # 处理连接超时、DNS失败等异常 return 'false' async def main(df): urls = df['listing_url'].tolist() async with aiohttp.ClientSession() as session: # 控制并发数,避免触发目标网站反爬或服务器拒绝 semaphore = asyncio.Semaphore(15) async def bounded_check(url): async with semaphore: return await check_url(session, url) # 批量并发执行请求 results = await asyncio.gather(*[bounded_check(url) for url in urls]) # 批量更新DataFrame,替代逐行修改的低效操作 df['condition'] = results return df # 异步环境中直接调用 # df_1 = await main(df_1) # 普通脚本中使用 # asyncio.run(main(df_1))
方案二:多线程(适配传统同步逻辑)
利用ThreadPoolExecutor实现多线程并发,无需切换异步思维,同样能显著提升速度。
import requests from concurrent.futures import ThreadPoolExecutor import pandas as pd def check_url(session, url): try: with session.head(url, allow_redirects=False, stream=True, timeout=5) as response: return 'active' if response.status_code == 200 else 'false' except Exception: return 'false' def main(df): urls = df['listing_url'].tolist() with requests.Session() as session: # 线程池大小建议10-20,避免资源过载 with ThreadPoolExecutor(max_workers=15) as executor: results = list(executor.map(lambda url: check_url(session, url), urls)) df['condition'] = results return df df_1 = main(df_1)
额外优化细节
- 添加
timeout参数:避免单个请求长时间阻塞拖慢整体进度。 - 增加重试机制:对临时失败的请求(如网络波动)进行有限次数重试,可借助
tenacity库实现。 - 复用会话:不管是
requests.Session还是aiohttp.ClientSession,都能复用TCP连接,减少握手开销。
内容的提问来源于stack exchange,提问作者Victor Guindani
相关产品推荐
相关产品推荐

