为执行时间为30分钟的脚本制作网页接口

7 投票
6 回答
3245 浏览
提问于 2025-04-15 18:15

我写了一个Python脚本,用来处理一些CSV文件中的数据。这个脚本的运行时间根据CSV文件的大小不同,大概需要3到30分钟才能完成。

现在我想给这个脚本加一个网页界面,这样我就可以从任何地方上传CSV数据文件。我写了一个基本的HTTP POST上传页面,并使用了Python的CGI模块,但脚本运行一段时间后就超时了。

这个脚本在开始时会输出一些HTTP头信息,然后在处理CSV的每一行时输出一些数据。举个例子,这个打印语句大约每30秒会触发一次。

# at the very top, with the 'import's
print "Content-type: text/html\n\n Processing ... <br />"

# the really long loop.
for currentRecord in csvRecords:
    count = count + 1
    print "On line " + str(count) + " <br />"

我以为浏览器会收到这些头信息,然后继续等待,因为它会不断接收到一些小数据。但实际上似乎发生的情况是,浏览器根本没有收到任何数据,当处理一个包含很多行的CSV时,就会出现Error 504超时错误。

也许在某个地方发生了缓存?从日志来看,

[Wed Jan 20 16:59:09 2010] [error] [client ::1] Script timed out before returning headers: datacruncher.py, referer: http://localhost/index.htm
[Wed Jan 20 17:04:09 2010] [warn] [client ::1] Timeout waiting for output from CGI script /Library/WebServer/CGI-Executables/datacruncher.py, referer: http://localhost/index.htm

解决这个问题的最好方法是什么?或者说,在浏览器中运行这样的脚本合适吗?

编辑:这个脚本是我自己用的,通常我打算在我的电脑上使用它,但我觉得一个基于网页的界面在旅行时或者从手机上使用会很方便。此外,实际上没有什么需要下载的内容——这个脚本最终很可能会通过电子邮件发送一份报告。

6 个回答

4

你可能需要使用 stdout.flush(),因为在你写满一整页的数据之前,脚本其实并没有真正把任何东西写到网络服务器上,而这通常是在超时之前不会发生的。

不过,解决这个问题的正确方法是,像其他人建议的那样,把处理过程放在一个单独的线程或进程中,然后给用户展示一个自动刷新的页面,显示处理状态,可以加个进度条或者其他好看的视觉效果,让他们不会觉得无聊。

5

我之前遇到过这种情况,我使用了定时任务。HTTP脚本会把要执行的任务(比如数据库操作或者在某个文件夹里的文件)写入一个队列里,然后定时任务会读取这个队列,执行这些任务。

12

我会把工作分成以下几个部分:

  1. 首先需要一个网页应用的地址,这个地址可以接收上传的CSV文件。这个网页应用会把CSV文件里的内容放到一个离线队列里,比如说一个数据库表。网页应用的回应应该是一个唯一的ID,用来标识这个排队的项目(可以使用自动递增的ID列)。客户端需要保存这个ID,以便在第三部分使用。

  2. 接下来是一个独立的服务应用,它会定期检查这个队列,看看有没有需要处理的工作。处理完成后,会把结果存储到另一个数据库表里,使用之前的唯一ID作为关键字。

  3. 最后需要一个网页应用的地址,可以用来获取处理结果,格式是 http://server/getresults/uniqueid/。如果处理已经完成(也就是说在结果数据库表里找到了这个唯一ID),那么就返回结果。如果还没完成,回应应该是一个代码来表示这个状态。比如可以用自定义的HTTP头,HTTP状态回应,或者回应内容写上'PENDING'(待处理)之类的。

撰写回答