我有一个正在运行的脚本,正在测试一系列可用的网址。
这是其中一项功能。
def checkUrl(url): # Only downloads headers, returns status code.
p = urlparse(url)
conn = httplib.HTTPConnection(p.netloc)
conn.request('HEAD', p.path)
resp = conn.getresponse()
return resp.status
有时候,VPS会失去连接,整个脚本会在发生这种情况时崩溃。
File "/usr/lib/python2.6/httplib.py", line 914, in request
self._send_request(method, url, body, headers)
File "/usr/lib/python2.6/httplib.py", line 951, in _send_request
self.endheaders()
File "/usr/lib/python2.6/httplib.py", line 908, in endheaders
self._send_output()
File "/usr/lib/python2.6/httplib.py", line 780, in _send_output
self.send(msg)
File "/usr/lib/python2.6/httplib.py", line 739, in send
self.connect()
File "/usr/lib/python2.6/httplib.py", line 720, in connect
self.timeout)
File "/usr/lib/python2.6/socket.py", line 561, in create_connection
raise error, msg
socket.error: [Errno 101] Network is unreachable
我根本不熟悉在python中处理这样的错误。
当网络连接暂时丢失时,防止脚本崩溃的适当方法是什么?
编辑:
我最终得到了这个 - 反馈?
def checkUrl(url): # Only downloads headers, returns status code.
try:
p = urlparse(url)
conn = httplib.HTTPConnection(p.netloc)
conn.request('HEAD', p.path)
resp = conn.getresponse()
return resp.status
except IOError, e:
if e.errno == 101:
print "Network Error"
time.sleep(1)
checkUrl(url)
else:
raise
我不确定我是否完全明白加注的内容..
答案 0 :(得分:4)
如果由于递归导致单个URL上的错误太多(默认情况下为> 1000),那么您的解决方案问题就是您将耗尽堆栈空间。此外,额外的堆栈帧可能使回溯难以阅读(500次调用checkURL
)。我将其重写为迭代,如下所示:
def checkUrl(url): # Only downloads headers, returns status code.
while True:
try:
p = urlparse(url)
conn = httplib.HTTPConnection(p.netloc)
conn.request('HEAD', p.path)
resp = conn.getresponse()
return resp.status
except IOError as e:
if e.errno == 101:
print "Network Error"
time.sleep(1)
except:
raise
此外,您希望try
中的最后一个字段为裸except
而不是else
。如果控件属于else
套件,那么try
只会被执行,因为try
套件的最后一个语句是return
,所以这种情况永远不会发生。
这很容易更改以允许有限次数的重试。只需将while True:
行更改为for _ in xrange(5)
或您希望接受的重试次数。如果5次尝试后无法连接到站点,则该函数将返回None
。您可以通过在函数的最后添加return
或raise SomeException
来使其返回其他内容或引发异常(缩进与for
或while
行相同)
答案 1 :(得分:3)
如果您只想处理此网络无法访问101,并且让其他异常抛出错误,您可以执行以下操作。
from errno import ENETUNREACH
try:
# tricky code goes here
except IOError as e:
# an IOError exception occurred (socket.error is a subclass)
if e.errno == ENETUNREACH:
# now we had the error code 101, network unreachable
do_some_recovery
else:
# other exceptions we reraise again
raise
答案 2 :(得分:0)
将try
... except:
放在您的代码周围以捕获异常。