2014-05-03 140 views
1

我有一个在启动时启动的脚本,并且可能在网络完全启动之前启动它。Python:在网络服务启动之前进行网络调用

如果在联网启动之前运行以下代码,则会失败,如果它稍后再次调用它会成功。

即使我将尝试次数增加到5分钟,它仍然会持续到5分钟,然后返回false,即使在脚本启动后网络出现可能少于30秒。

而不是在做任何尝试之前只休眠1分钟,有没有办法使以下代码工作,而不是死亡,如果以太网不起来?

self.TRIES = 60 
self.URL="http://www.somedomain.com" 

## Do we have internet 
def isup(): 
    try: 
    urllib2.urlopen(self.URL).close() 
    return True 
    except urllib2.URLError,e: 
    pass 
    return False 

## Try the lookup 
while (self.TRIES > 0): 
    if isup(): 
    check() 
    break 
    self.TRIES = self.TRIES-1 
    time.sleep(1) 

编辑

在开机系统(Arch Linux的)适配器(eth0的在这种情况下)和网络服务最初没有运行,并在启动过程已启动。

如果在网络服务完全启动之前调用urllib2(以及其他与网络相关的调用),则会死亡,并且随后的调用将始终导致失败。

这与断开以太网电缆不同,如果您只需拔掉以太网电缆并调用函数(class),则它将成功,但如果在调用网络服务之前调用该函数,它将会失败并死亡。

我可以通过在代码顶部添加一个time.sleep(30)来解决此问题,然后为O/S网络服务提供足够的时间来完全启动,并且脚本按预期工作100%。

+0

难道你不只是检查状态码? –

+0

在联网之前,你的意思是什么?你在做什么操作系统? –

+0

我也想知道你的意思是“联网之前”。我刚刚在我的机器上进行了测试,通过从网络断开连接,运行'urllib2.urlopen('http://www.yahoo.com').close()'的失败行,然后重新连接并再次尝试。它完美的作品。你有没有测试过,以确保它实际上正确地提取数据?只是因为你有网络连接并不意味着你有一个工作的DNS,有效的出站端口,等等。 – Namey

回答

0

你会做得一样:

def isup(): 
    try: 
    urllib2.urlopen(self.URL).close() 
    return True 
    except urllib2.URLError,e: 
    pass 
    return False 

## Try the lookup 
while not isup(): 
    pass   #or replace pass with time.sleep(1) or time.sleep(0.5) 
check() 
+0

谢谢,但如果我这样做,它会一直持续下去,这并不是说我的等待时间太短,但如果在网络不通时调用urllib2,它似乎会死掉! – crankshaft

0

你为什么不使用ping

def isUp(): 
    ret = os.system("ping -c 1 www.google.com") 
    return (ret != 0) 

注意:这不工作在Windows上为是,但你得到了主意......

2

使用请求,并检查状态代码?

import requests 
In [36]: r = requests.get('http://httpbin.org/get') 

In [37]: r.status_code == requests.codes.ok 
Out[37]: True 

In [38]: r.status_code 
Out[38]: 200 

200 
In [33]: r = requests.get('http://httpbin.org/bad') 

In [34]: r.status_code 
Out[34]: 404 

In [35]: r.status_code == requests.codes.ok 
Out[35]: False 

def isup(): 
    try: 
     r = requests.get(self.URL) 
     return r.status_code == requests.codes.ok 
    except Exception, e: 
     print e 
     return False