2013-03-25 60 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