如何用Python异步实现多网站按可变时间间隔重复下载?
我完全懂你的困扰——要给一堆网站按各自不同的时间间隔重复下载,还得异步并发,结果之前试了各种方法都只能串行,下一次下载非得等上一次全做完才开始,效率实在太低了!
别慌,咱们用asyncio搭配aiohttp就能完美解决这个需求,这俩是Python异步HTTP处理的黄金组合。下面直接上可运行的代码和关键思路解析:
核心思路
- 给每个URL单独创建一个异步任务,每个任务独立循环执行「下载网站 → 等待指定间隔 → 再次下载」的逻辑
- 所有任务同时在事件循环中运行,互不阻塞,真正实现并发
- 复用
aiohttp.ClientSession来提升请求效率,避免频繁创建/销毁HTTP连接
完整代码实现
首先得先安装依赖:
pip install aiohttp
然后是代码:
import asyncio import aiohttp from typing import List, Tuple async def download_website(session: aiohttp.ClientSession, url: str) -> None: """异步下载单个网站的函数,处理请求和异常""" try: async with session.get(url) as response: # 这里可以根据需求处理响应内容,比如读取文本、保存到文件等 content_length = response.headers.get("Content-Length", "未知") print(f"成功下载 {url} | 状态码: {response.status} | 内容大小: {content_length}") except Exception as e: print(f"下载 {url} 失败: {str(e)}") async def repeat_download_task(url: str, interval: int, session: aiohttp.ClientSession) -> None: """单个URL的重复下载任务,按指定间隔循环执行""" while True: await download_website(session, url) # 等待指定间隔,这里的sleep不会阻塞其他任务 await asyncio.sleep(interval) async def main(url_intervals: List[Tuple[str, int]]) -> None: """主函数,创建所有并发任务并启动事件循环""" # 创建一个复用的ClientSession,推荐在所有请求中复用它 async with aiohttp.ClientSession() as session: # 为每个URL创建一个异步任务 tasks = [ asyncio.create_task(repeat_download_task(url, interval, session)) for url, interval in url_intervals ] # 等待所有任务一直运行(因为都是无限循环,除非手动终止) await asyncio.gather(*tasks) if __name__ == "__main__": # 示例:定义需要下载的URL和对应的重复间隔(单位:秒) url_list = [ ("https://example.com", 10), # 每10秒下载一次 ("https://httpbin.org/get", 5), # 每5秒下载一次 ("https://github.com", 30), # 每30秒下载一次 ] # 启动事件循环 asyncio.run(main(url_list))
关键细节解析
- 并发任务创建:用
asyncio.create_task把每个URL的循环任务包装成异步任务,这样它们会被事件循环调度,同时运行 - 非阻塞等待:
asyncio.sleep(interval)只会让当前任务暂停,不会阻塞整个事件循环,其他任务该跑还是跑 - 连接复用:
aiohttp.ClientSession会自动管理连接池,复用HTTP连接,比每次请求创建新连接高效得多 - 异常处理:在
download_website里捕获了请求异常,避免单个URL的下载失败导致整个程序崩溃
使用说明
- 把
url_list换成你自己的URL和对应间隔 - 如果需要停止程序,直接按
Ctrl+C即可(asyncio会自动处理任务终止) - 要是需要对下载的内容做进一步处理(比如保存到文件、解析HTML),直接在
download_website函数里添加逻辑就行
这样实现后,每个URL都会按自己的间隔独立重复下载,完全不会互相等待,真正达到了你要的异步并发效果!
内容的提问来源于stack exchange,提问作者Cake
相关产品推荐
相关产品推荐

