如何在Flask应用运行时同时执行后台爬虫任务?
解决Flask后台运行定时爬虫的问题
你当前用subprocess.call失败的原因是:这个方法是阻塞调用,会等待爬虫脚本执行完毕才继续往下走,但你的crawling.py里有while True死循环,永远不会结束,导致Flask的app.run()根本没机会执行。
下面给你几个可行的解决方案:
方案一:用subprocess.Popen实现后台子进程
修改app.py里的crawling函数,换成非阻塞的Popen:
from flask import Flask import subprocess app = Flask(__name__) def crawling(): # 直接启动子进程,不等待它结束 subprocess.Popen( ['python3', 'crawling.py'], stdout=subprocess.PIPE, stderr=subprocess.PIPE ) @app.route('/') def hello(): return "Hello Flask!" if __name__ == '__main__': crawling() app.run('0.0.0.0', port=5000, debug=True)
这样爬虫会在后台子进程运行,Flask主进程能正常启动。
方案二:把定时任务放到Flask的线程中运行
不需要单独的crawling.py脚本,直接把定时任务逻辑放到Flask的线程里:
先调整crawling.py,把核心函数暴露出来:
from pymongo import MongoClient import json import requests import schedule import time def connectDB(): # 补充你的数据库连接逻辑 client = MongoClient('mongodb://localhost:27017/') return client['your_database'] def fetchAndStoreData(db): # 你的数据抓取和存储逻辑 print("正在抓取数据...") def start_scheduler(db): schedule.every(10).seconds.do(fetchAndStoreData, db) while True: schedule.run_pending() time.sleep(1)
然后修改app.py,用线程启动定时任务:
from flask import Flask import threading from crawling import connectDB, start_scheduler app = Flask(__name__) @app.route('/') def hello(): return "Hello Flask!" if __name__ == '__main__': db = connectDB() # 启动后台线程,daemon=True表示Flask退出时线程自动终止 threading.Thread(target=start_scheduler, args=(db,), daemon=True).start() app.run('0.0.0.0', port=5000, debug=True)
方案三:命令行分别运行两个进程
这是生产环境中更推荐的方式,便于分别管理日志和进程:
- 打开第一个终端,运行爬虫:
python3 crawling.py - 打开第二个终端,运行Flask:
python3 app.py
这种方式逻辑清晰,出现问题时能单独排查爬虫或Flask的问题。
内容的提问来源于stack exchange,提问作者minsuhan
相关产品推荐
相关产品推荐

