如何实现Python定时爬取并将数据传递至Flask HTML页面?
Flask定时爬虫数据渲染问题修复
错误原因
你遇到的TypeError: home() missing 1 required positional argument: 'data',核心问题是Flask路由函数不能定义额外的位置参数——Flask处理请求时只会传入路由规则里的变量(比如<int:id>这类),不会自动传递data参数。另外,直接在主线程里用while True + time.sleep会阻塞Flask的请求处理,导致服务无法响应页面请求。
修复方案
1. 封装爬虫函数并存储全局数据
把爬取逻辑封装成独立函数,用全局变量存储最新爬取结果,让路由函数可以直接读取这个变量。
2. 用线程运行定时任务
单独开启后台线程执行定时爬取,避免阻塞Flask的主线程请求处理。
3. 修正路由函数参数
移除路由函数的data参数,在函数内部直接读取全局变量的最新数据。
修改后的完整代码
from flask import Flask, render_template from bs4 import BeautifulSoup import requests import time from threading import Thread app = Flask(__name__) # 全局变量存储最新爬取的数据 latest_data = [] def scrape(): global latest_data url = 'https://www.espn.com/golf/leaderboard/_/tournamentId/401465506' req = requests.get(url) bsObj = BeautifulSoup(req.text, 'lxml') table_data = [] tablerows = bsObj.select('table tr') for tr in tablerows[1:]: row = [] for t in tr.select('td')[1:4]: row.extend([t.text.strip()]) table_data.append(row) # 更新全局变量为最新数据 latest_data = table_data def run_scheduled_scrape(): # 程序启动时先爬一次初始化数据 scrape() while True: time.sleep(60) # 每分钟执行一次爬取 scrape() @app.route('/') def home(): # 直接读取全局变量的最新数据传给模板 return render_template('home.html', data=latest_data) if __name__ == '__main__': # 启动后台定时任务线程,daemon=True确保Flask退出时线程自动结束 Thread(target=run_scheduled_scrape, daemon=True).start() app.run(debug=True)
关键改动说明
- 全局变量
latest_data:作为数据中转站,存储每次爬取的最新结果,路由函数直接读取这个变量传递给模板。 scrape()函数:独立封装爬取逻辑,每次执行后更新全局变量,保证数据是最新的。- 后台线程定时任务:用
Thread开启后台线程执行定时爬取,不会阻塞Flask主线程的请求处理,daemon=True避免程序退出时线程残留。 - 路由函数修正:移除多余的
data参数,符合Flask路由函数的定义规则,内部直接调用全局变量获取数据。
内容的提问来源于stack exchange,提问作者Mike Dietrich
相关产品推荐
相关产品推荐

