【问题标题】:Check if the internet cannot be accessed in Python检查是否无法在 Python 中访问互联网
【发布时间】:2010-04-24 01:11:44
【问题描述】:

我有一个应用程序向 Internet 上的特定 URL 发出 HTTP GET 请求。但是当网络出现故障时(例如,没有公共 wifi - 或者我的 ISP 出现故障或类似情况),我会在 urllib2.urlopen 获得以下回溯:

70, in get
    u = urllib2.urlopen(req)
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 126, in urlopen
    return _opener.open(url, data, timeout)
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 391, in open
    response = self._open(req, data)
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 409, in _open
    '_open', req)
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 369, in _call_chain
    result = func(*args)
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 1161, in http_open
    return self.do_open(httplib.HTTPConnection, req)
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 1136, in do_open
    raise URLError(err)
URLError: <urlopen error [Errno 8] nodename nor servname provided, or not known>

我想向用户打印一个友好的错误,告诉他他的网络可能已关闭,而不是这个不友好的“提供节点名或服务名”错误消息。当然我可以捕获URLError,但这会捕获每个 url 错误,而不仅仅是与网络停机时间相关的错误。

我不是一个纯粹主义者,所以即使是“无法访问服务器 example.com;服务器确实有问题或者您的网络连接已关闭”这样的错误消息也会很好。如何有选择地捕获此类错误? (首先,如果 DNS 解析在 urllib2.urlopen 失败,可以合理地假设为网络不可访问?如果是这样,我如何在 except 块中“捕获”它?)

【问题讨论】:

  • 如果我正确阅读了问题的子文本,那么在往返网络服务器的过程中有太多组件,您可以肯定地说您无法获得网址。 DNS 错误并不意味着数据链接错误,它可能是 DNS 服务器故障或端口过滤器或任何其他原因。如今,鉴于您的默认路由器可能设置为(例如)忽略 ICMP ECHO 请求,您无法真正从应用层为用户诊断网络故障。

标签: python exception networking urllib2


【解决方案1】:

您应该将请求包装在 try/except 语句中,以便您发现错误,然后让他们知道。

try:
   u = urllib2.urlopen(req)
except HTTPError as e:
   #inform them of the specific error here (based off the error code)
except URLError as e:
   #inform them of the specific error here
except Exception as e:
   #inform them that a general error has occurred 

【讨论】:

  • 这是我最终使用的,除了... HTTPError 应该高于 URLError。如果你能解决这个问题,我会将你的答案标记为正确。
  • 但是我有 URLError 和 HTTPError 因为两者都可能发生在那里。
  • 但是URLError - 作为一个基类 - 也会捕获HTTPError。我会自己编辑。
【解决方案2】:

urllib2 - The Missing Manual 有一个很好的部分介绍了如何处理 URLError 和 HTTPError 异常以及如何区分导致它们的条件。

【讨论】:

    【解决方案3】:

    捕获URLError,然后测试reason 属性怎么样?如果原因不是您感兴趣的原因,请重新发送URLError 并在其他地方处理。

    或者,您可以尝试httplib2。它的ServerNotFoundError 例外可能会满足您的需求。

    【讨论】:

    • reasonsocket.gaierror 的一个实例,它在任何纯 Python 库代码中都找不到。试图找到它...
    • 问题:urlopen 也可以通过 HTTPError (except URLError 也捕获它)。不确定它是否还会引发其他错误。
    猜你喜欢
    • 2016-09-10
    • 1970-01-01
    • 1970-01-01
    • 2015-11-12
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多