2013-03-25 29 views
1

我是使用異常處理的新手。我正在使用機械化模塊來抓取多個網站。我的程序經常失敗,因爲連接速度很慢,並且請求超時。我希望能夠在每次嘗試之間的30秒延遲後重試網站(例如超時),最多可重試5次。處理來自urllib2的異常和在Python中機械化

我看着this stackoverflow答案,可以看到我如何處理各種異常。我也看到了(雖然看起來很笨拙),我怎麼可以把try/exception放在while循環中來控制5次嘗試......但我不明白如何跳出循環,或者當連接時「繼續」是成功的,並沒有拋出異常。

from mechanize import Browser 
import time 

b = Browser() 
tried=0 
while tried < 5: 
    try: 
    r=b.open('http://www.google.com/foobar') 
    except (mechanize.HTTPError,mechanize.URLError) as e: 
    if isinstance(e,mechanize.HTTPError): 
     print e.code 
     tried += 1 
     sleep(30) 
     if tried > 4: 
     exit() 
    else: 
     print e.reason.args 
     tried += 1 
     sleep(30) 
     if tried > 4: 
     exit() 

print "How can I get to here after the first successful b.open() attempt????" 

我將不勝感激約(1)如何打破循環的一個成功的開放的意見,和(2)如何使整個街區少笨拙/更優雅。

回答

1

無論在哪種情況下,您都不必在except塊中重複這些事情。

from mechanize import Browser 
import time 

b = Browser() 
tried=0 
while True: 
    try: 
    r=b.open('http://www.google.com/foobar') 
    except (mechanize.HTTPError,mechanize.URLError) as e: 
     tried += 1 
    if isinstance(e,mechanize.HTTPError): 
     print e.code 
    else: 
     print e.reason.args 
    if tried > 4: 
     exit() 
    sleep(30) 
    continue 
    break 

此外,您可能能夠使用while not r:取決於什麼Browser.open回報。

編輯:roadierich顯示更優雅的方式與

try: 
    doSomething() 
    break 
except: 
    ... 

由於錯誤跳到除了塊。

1

對於你的第一個問題,你只需要打破循環的「break」關鍵字。

對於第二個問題,對於不同種類的例外,您可以爲一個「嘗試」設置幾個「except」子句。這取代了你的isinstance()檢查,並會使你的代碼更清晰。

4

你的第一個問題可以用break做到:

while tried < 5: 
    try: 
    r=b.open('http://www.google.com/foobar') 
    break 
    except #etc... 

真正的問題,但是,你真的想:這就是被稱爲「意大利麪條代碼」:如果你嘗試圖的執行通過該計劃,它看起來像一盤意大利麪條。

您遇到的實際(imho)問題是您退出while循環的邏輯有缺陷。而不是嘗試,直到你已經有了一個連接,停止了一些嘗試(即不會發生,因爲你已經離開反正一個條件)後,循環:

#imports etc 

tried=0 
connected = False 
while not Connected: 
    try: 
     r = b.open('http://www.google.com/foobar') 
     connected = true # if line above fails, this is never executed 
    except mechanize.HTTPError as e: 
     print e.code    
     tried += 1   
     if tried > 4: 
      exit() 
     sleep(30) 

    except mechanize.URLError as e: 
     print e.reason.args    
     tried += 1 
     if tried > 4: 
      exit()   
     sleep(30) 

#Do stuff 
+0

謝謝所有。我完全贊同關於意大利麪代碼的評論。當我問到試圖擺脫笨拙/不雅時,你的建議正是我尋找的那種東西。我也很欣賞我的代碼不僅簡單而且不合邏輯。我將納入更改。 – user02814 2013-03-26 07:21:31