2014-05-03 134 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