Django函数中实现多站点GET请求循环并行执行的方法咨询
实现Django中多站点GET请求的并行执行
一、直接在函数内用Python标准库实现(同步函数内并行)
针对IO密集型的网络请求,用Python标准库的concurrent.futures.ThreadPoolExecutor就能快速实现并行,不需要额外依赖:
from concurrent.futures import ThreadPoolExecutor import requests from .models import WebSite # 单独封装站点数据抓取逻辑 def fetch_site_data(web): try: response = requests.get(web.url, timeout=10) # 这里替换成你的数据处理逻辑,比如保存到模型 web.data = response.text web.save() return f"成功抓取 {web.url}" except Exception as e: return f"抓取 {web.url} 失败: {str(e)}" def fetch_all_sites(): web_sites = WebSite.objects.all() # 初始化线程池,最大工作线程数设为站点数量或固定值(比如10) with ThreadPoolExecutor(max_workers=10) as executor: # 批量提交任务并获取结果 results = list(executor.map(fetch_site_data, web_sites)) # 可根据结果做后续处理,比如打印日志 for result in results: print(result)
这种方式直接在函数内完成并行,线程池会自动调度任务,注意要捕获请求异常,避免单个站点的失败中断整个并行流程。
二、用Celery实现异步并行(后台执行)
如果不想阻塞当前请求(比如用户操作后不用等待所有请求完成),可以用Celery做异步并行:
1. 先确保Django项目已配置好Celery(配置Redis/RabbitMQ作为broker)
2. 创建异步任务
# tasks.py from celery import shared_task import requests from .models import WebSite @shared_task def fetch_site_data_task(web_id): try: web = WebSite.objects.get(id=web_id) response = requests.get(web.url, timeout=10) web.data = response.text web.save() return f"{web.url} 抓取成功" except Exception as e: return f"{web.url} 抓取失败: {str(e)}"
3. 在业务函数中触发任务
from .tasks import fetch_site_data_task from .models import WebSite def trigger_parallel_fetch(): web_sites = WebSite.objects.all() # 给每个站点提交一个异步任务 for web in web_sites: fetch_site_data_task.delay(web.id) # 直接返回响应,任务在后台由Celery Worker并行执行 return "抓取任务已在后台启动"
这种方式适合不需要立即获取结果的场景,任务由Celery Worker并行处理,不会占用Django请求线程。注意任务中要通过id查询模型,避免直接传递模型对象导致序列化问题。
内容的提问来源于stack exchange,提问作者snorlaxPk
相关产品推荐
相关产品推荐

