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

如何获取Celery完成任务的结果并在Flask中存储为变量?

解决Celery任务结果返回至Flask应用的问题

核心问题分析

你当前的代码存在两个关键问题:

  • Celery未配置结果后端,任务执行结果无法持久化,导致app.py无法获取
  • app.py中错误调用两次tasks.scope,且传入的marketplace[0]是字符串首字符而非完整名称;同时直接调用任务是同步执行,既没利用Celery异步特性,也无法获取异步结果

步骤1:配置Celery结果后端并修复Selenium逻辑

修改tasks.py,添加结果后端配置(推荐和broker一致用Redis),同时修复WebDriver初始化问题(每个任务单独创建实例,避免并发冲突):

from celery import Celery
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 配置消息队列和结果存储后端
celery = Celery(
    broker='redis://127.0.0.1:6379',
    result_backend='redis://127.0.0.1:6379'
)

@celery.task()
def scope(marketplace):
    # 每个任务单独初始化WebDriver
    web = webdriver.Chrome()  # 根据你的浏览器调整,如Firefox
    try:
        web.get(f'https://magiceden.io/marketplace/{marketplace}')
        # 获取价格文本
        price_check = WebDriverWait(web,30).until(
            EC.visibility_of_element_located((By.XPATH, "/html/body/div[2]/div[2]/div[3]/div[2]/div[2]/div[3]/div[2]/div[4]/div/div[2]/div[1]/div[2]/div/div[2]/div/div[2]/div/span/div[2]/div/span[1]"))
        ).text
        # 获取图片src(WebElement无法序列化,需提取可存储的字符串)
        image_src = WebDriverWait(web,30).until(
            EC.visibility_of_element_located((By.XPATH, "/html/body/div[2]/div[2]/div[3]/div[2]/div[2]/div[3]/div[2]/div[4]/div/div[2]/div[1]/div[2]/div/div[1]/div/div/img"))
        ).get_attribute('src')
        return (price_check, image_src)
    finally:
        # 确保任务结束后关闭浏览器
        web.quit()

步骤2:在app.py中获取任务结果

修改app.py,通过Celery的AsyncResult对象获取异步任务结果:

import tasks

marketplace = 'cheddar_block_games'

# 异步提交任务,返回任务状态对象
task = tasks.scope.delay(marketplace)

# 等待任务完成并获取结果(可设置超时,避免无限等待)
result = task.get(timeout=30)

# 解构结果赋值给目标变量
price_check, image_src = result

额外优化建议(针对Flask请求场景)

如果是在Flask的HTTP请求中,直接用task.get()会阻塞请求20秒导致超时,建议改用异步视图+前端轮询的方式:

from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/start-check')
def start_check():
    marketplace = 'cheddar_block_games'
    task = tasks.scope.delay(marketplace)
    # 返回任务ID,让前端轮询获取结果
    return jsonify({'task_id': task.id})

@app.route('/task-status/<task_id>')
def task_status(task_id):
    task = tasks.scope.AsyncResult(task_id)
    if task.state == 'SUCCESS':
        return jsonify({
            'state': task.state,
            'price_check': task.result[0],
            'image_src': task.result[1]
        })
    else:
        return jsonify({'state': task.state})

确保Redis服务正常运行,Celery Worker启动命令:celery -A tasks worker --loglevel=info

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 22:33:25