【问题标题】:What errors/exceptions do I need to handle with urllib2.Request / urlopen?我需要使用 urllib2.Request / urlopen 处理哪些错误/异常?
【发布时间】:2010-10-14 12:58:40
【问题描述】:

我有以下代码可以回发到远程 URL:

request = urllib2.Request('http://www.example.com', postBackData, { 'User-Agent' : 'My User Agent' })

try: 
    response = urllib2.urlopen(request)
except urllib2.HTTPError, e:
    checksLogger.error('HTTPError = ' + str(e.code))
except urllib2.URLError, e:
    checksLogger.error('URLError = ' + str(e.reason))
except httplib.HTTPException, e:
    checksLogger.error('HTTPException')

postBackData 是使用使用 urllib.urlencode 编码的字典创建的。 checksLogger 是一个使用logging 的记录器。

当远程服务器关闭并且代码退出时,我遇到了此代码运行的问题(这是在客户服务器上,所以我现在不知道退出堆栈转储/错误是什么)。我假设这是因为存在未处理的异常和/或错误。那么是否还有其他我没有在上面处理的可能触发的异常?

【问题讨论】:

    标签: python


    【解决方案1】:

    添加通用异常处理程序:

    request = urllib2.Request('http://www.example.com', postBackData, { 'User-Agent' : 'My User Agent' })
    
    try: 
        response = urllib2.urlopen(request)
    except urllib2.HTTPError, e:
        checksLogger.error('HTTPError = ' + str(e.code))
    except urllib2.URLError, e:
        checksLogger.error('URLError = ' + str(e.reason))
    except httplib.HTTPException, e:
        checksLogger.error('HTTPException')
    except Exception:
        import traceback
        checksLogger.error('generic exception: ' + traceback.format_exc())
    

    【讨论】:

    • 在您的示例中 checksLogger.error 是用户定义的函数吗?
    • @algotr8der: 是的,这只是问题的复制粘贴
    • socket.error(或其父 IOError)是另一个可以显式捕获的异常。例如stackoverflow.com/questions/20568216/…
    【解决方案2】:

    docs pageurlopen 条目看来,您只需要捕获URLError。如果您真的想对冲 urllib 代码中的问题,您还可以将Exception 作为后备。 不要只使用except:,因为这也会捕获SystemExitKeyboardInterrupt

    编辑:我的意思是,你正在捕捉它应该抛出的错误。如果它抛出其他东西,可能是由于 urllib 代码没有捕获它应该捕获并包裹在 URLError 中的东西。即使是标准库也往往会遗漏AttributeError 之类的简单内容。捕获 Exception 作为后备(并记录捕获的内容)将帮助您弄清楚发生了什么,而不会捕获 SystemExitKeyboardInterrupt

    【讨论】:

    • +1 获取文档链接,以及关于异常的简洁建议
    • +1 让我知道 except: 和 except Exception(至少其中一个)之间的区别。
    • 文档页面是404
    • @Priyank,不再是 :)
    【解决方案3】:
    $ grep "raise" /usr/lib64/python/urllib2.py
    IOError); for HTTP errors, raises an HTTPError, which can also be
            raise AttributeError, attr
                    raise ValueError, "unknown url type: %s" % self.__original
            # XXX raise an exception if no one else should try to handle
            raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
            perform the redirect.  Otherwise, raise HTTPError if no-one
                raise HTTPError(req.get_full_url(), code, msg, headers, fp)
                    raise HTTPError(req.get_full_url(), code,
                raise HTTPError(req.get_full_url(), 401, "digest auth failed",
                    raise ValueError("AbstractDigestAuthHandler doesn't know "
                raise URLError('no host given')
                raise URLError('no host given')
                raise URLError(err)
            raise URLError('unknown url type: %s' % type)
            raise URLError('file not on local host')
                raise IOError, ('ftp error', 'no host given')
                raise URLError(msg)
                raise IOError, ('ftp error', msg), sys.exc_info()[2]
                raise GopherError('no host given')
    

    urllib2 依赖也有可能出现异常,或者是真正的 bug 引起的异常。

    您最好通过自定义sys.excepthook 在文件中记录所有未捕获的异常。 这里的关键经验法则是永远不要捕获您不打算更正的异常,并且记录不是更正所以不要'抓到它们只是为了记录它们。

    【讨论】:

      【解决方案4】:

      您可以捕获所有异常并记录捕获的内容:

       import sys
       import traceback
       def formatExceptionInfo(maxTBlevel=5):
           cla, exc, trbk = sys.exc_info()
           excName = cla.__name__
           try:
               excArgs = exc.__dict__["args"]
           except KeyError:
               excArgs = "<no args>"
           excTb = traceback.format_tb(trbk, maxTBlevel)
           return (excName, excArgs, excTb)
       try:
           x = x + 1
       except:
           print formatExceptionInfo()
      

      (来自http://www.linuxjournal.com/article/5821的代码)

      另请阅读documentation on sys.exc_info

      【讨论】:

      • 最好使用“except Exception:”,这样您就不会捕获会导致您的 except 处理程序出现问题的错误。
      • 如果您只是记录异常,最好不要捕获异常——请参阅我的回答。
      • @Steven Huwig:是的,但我发现即使使用异常钩子也很笨拙——我最好在服务器上添加一些日志记录,例如 somescript.py 2>/var/tmp/scrape。日志
      【解决方案5】:

      我抓住了:

      httplib.HTTPException
      urllib2.HTTPError
      urllib2.URLError
      

      我相信这涵盖了包括套接字错误在内的所有内容。

      【讨论】:

      • urllib2.HTTPErrorurllib2.URLError 的子类,所以抓住第二个就足够了
      猜你喜欢
      • 2017-01-01
      • 2012-04-16
      • 2023-03-18
      • 1970-01-01
      • 2018-01-26
      • 2014-12-24
      • 1970-01-01
      • 1970-01-01
      • 2012-01-12
      相关资源
      最近更新 更多