2011-12-25 342 views
2

我有一个网页爬行python脚本在终端运行了几个小时,这是不断填充我的数据库。它有几个嵌套for循环。出于某些原因,我需要重新启动计算机,并从我离开的地方继续执行我的脚本。是否可以保持指针状态并恢复终端中以前运行的脚本?如何暂停在终端运行的python脚本

我正在寻找一种解决方案,它将在不改变python脚本的情况下工作。修改代码的优先级较低,因为这意味着重新启动程序并重新投入时间。

更新: 感谢VM的建议。我会采取的。为了完成,应该对脚本进行什么样的通用修改以使其暂停和恢复?

Update2: VM上的移植工作正常。我还修改了脚本,使其能够防止网络故障。代码如下。

+2

休眠你的电脑! – Hossein 2011-12-25 17:10:41

+1

在虚拟机中运行它。 – 2011-12-25 17:16:16

+0

@Hossein我的Mac不支持休眠:(而且我不认为从休眠状态恢复将恢复我的爬行脚本正确 – jerrymouse 2011-12-25 17:42:42

回答

3

您可能尝试暂停计算机或在虚拟机中运行,随后可能会暂停计算机。但是,当您的脚本正在使用网络连接时,一旦您启动系统后,您的脚本将无法运行。暂停计算机并恢复它或保存虚拟M/C并恢复它意味着您需要重新建立网络连接。对于系统外部的任何元素都是如此,网络就是其中之一。如果你使用的是动态网络,那么很有可能你下次开机的时候会得到一个新的IP,而你以前工作的网络状态将是无效的。

如果您打算修改脚本,您需要保留一些注意事项。

  1. 添加序列化和反序列化功能。 Python有腌菜和更快的cPickle方法来做到这一点。
  2. 添加重新开始分。这样做的最好方法是定期保存状态,并在重新启动脚本时,在建立所有瞬态元素(如网络)后,从上次保存的状态重新启动。

这不会是一件容易的任务,以便考虑投资的时间considrable量:-)

注意***

退一步。有一种方法可以改变脚本。您可以尝试使用云端虚拟化解决方案,如Amazon EC2。

1

正如其他人所评论的,除非您在可以挂起的虚拟机中运行脚本,否则您需要修改脚本以跟踪其状态。

0

如果此问题足够重要以保证这种财务投资,则可以在虚拟机上运行脚本。当您需要关闭时,暂停虚拟机,然后关闭计算机。当您想再次启动时,启动计算机,然后唤醒虚拟机。

+0

您是否尝试过这种?网络和数据库连接怎么样? – reclosedev 2011-12-25 17:28:54

+0

@reclosedev我还没试过。让脚本运行一段时间,然后将其移植到VM并重试。 – jerrymouse 2011-12-25 17:47:51

0

WinPDB是一个支持远程调试的python调试器。我从来没有使用它,不知道是否远程调试正在运行的进程需要对脚本进行修改(这很可能会导致安全问题);但如果在不修改脚本的情况下进行远程调试是可能的,那么您可能能够将脚本的当前状态转储到文件中,并在以后找出如何加载它。我不认为它会工作。

1

由于您正在使用您的数据填充数据库,因此我建议将其用作跟踪脚本进度的方式(获取最新的URL解析,获取挂起的URL列表等)。

如果脚本突然终止,您不必担心保存其状态,因为数据库事务将救援并且只有您提交的数据将被保存。

脚本重新启动后,只会存储完整处理的URL的数据,您可以继续根据数据库提取下一个URL。

1

我将脚本移植到VM并从那里启动它。但是,从休眠状态恢复后出现网络连接故障。下面是我如何解决它通过调整python脚本:

import logging 
import socket 
import time 
socket.setdefaulttimeout(30) #set timeout in secs 
maxretry = 10 #set max retries 
sleeptime_between_retry = 1 #waiting time between retries 

erroroccured = 0 
while True: 
    try: 
     domroot = parse(urllib2.urlopen(myurl)).getroot() 
    except Exception as e: 
     erroroccured += 1 
     if erroroccured>maxretry: 
      logger.info("Maximum retries reached. Quitting this leg.") 
      break 
     time.sleep(sleeptime_between_retry) 
     logging.info("Network error occurred. Retrying %d time..."%(erroroccured)) 
     continue 
    finally: 
     #common code to execute after try or except block, if any 
     pass 
    break 

这一修改使我的脚本证明脾气网络故障。