3

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

我正在寻找一种无需更改 python 脚本即可工作的解决方案。修改代码的优先级较低,因为这意味着重新启动程序并重新投入时间。

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

更新2:在 VM 上移植工作正常。我还修改了脚本以使其免受网络故障的影响。下面写的代码。

4

6 回答 6

4

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

如果您打算修改脚本,则需要牢记几件事。

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

这不是一件容易的事,所以考虑投入大量时间:-)

笔记***

转念一想。更改脚本有另一种选择。您可以尝试使用 Amazon EC2 等云虚拟化解决方案。

于 2011-12-25T17:28:05.967 回答
2

我将我的脚本移植到 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

这种修改使我的脚本能够抵御网络故障。

于 2011-12-26T14:10:11.460 回答
1

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

于 2011-12-25T17:18:27.410 回答
1

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

如果脚本突然终止,您不必担心保存它的状态,因为数据库事务会派上用场,只有您提交的数据会被保存。

当脚本重新启动时,只会存储您完全处理的 URL 的数据,您可以继续根据数据库选择下一个 URL。

于 2011-12-25T19:10:56.307 回答
0

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

于 2011-12-25T17:19:51.403 回答
0

WinPDB是一个支持远程调试的 python 调试器。我没用过,不知道远程调试一个正在运行的进程是否需要修改脚本(很有可能,否则就是安全问题);但是如果可以在不修改脚本的情况下进行远程调试,那么您可以将脚本的当前状态转储到文件中,然后再弄清楚如何加载它。我不认为它会工作。

于 2011-12-25T17:30:33.117 回答