【问题标题】:Handling exceptions from urllib2 and mechanize in Python处理来自 urllib2 的异常并在 Python 中进行机械化
【发布时间】:2013-03-25 19:46:49
【问题描述】:

我是使用异常处理的新手。我正在使用 mechanize 模块来抓取几个网站。我的程序经常失败,因为连接速度慢并且请求超时。我希望能够在每次尝试之间延迟 30 秒后重试网站(例如超时)最多 5 次。

我查看了this stackoverflow 的答案,可以看到我如何处理各种异常。我也看到(虽然它看起来很笨拙)我如何将尝试/异常放在一个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) 如何使整个块不那么笨拙/更优雅的建议。

【问题讨论】:

    标签: python exception-handling mechanize-python


    【解决方案1】:

    您的第一个问题可以通过break

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

    然而,真正的问题是你真的想要:这就是所谓的“意大利面条代码”:如果你尝试通过程序绘制执行图,它看起来就像一盘意大利面条。

    您遇到的真正(恕我直言)问题是您退出 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
    

    【讨论】:

    • 谢谢大家。我完全同意关于意大利面条代码的评论。当我问到试图摆脱笨拙/不优雅时,你的建议正是我正在寻找的东西。我也很欣赏我的代码不仅不优雅而且不合逻辑的观点。我将合并这些更改。
    【解决方案2】:

    在任何一种情况下,您都不必在 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:
      ...
    

    因为错误会跳到 except 块。

    【讨论】:

      【解决方案3】:

      对于您的第一个问题,您只需要“break”关键字,它会跳出循环。

      对于第二个问题,您可以为一个“尝试”设置多个“除外”子句,用于不同类型的异常。这取代了您的 isinstance() 检查,并使您的代码更简洁。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多