使用Python请求精确捕获DNS错误

ana*_*nik 0 dns python-requests

我正在尝试使用来检查过期的域名python-requests

import requests

try:
    status = requests.head('http://wowsucherror')
except requests.ConnectionError as exc:
    print(exc)
Run Code Online (Sandbox Code Playgroud)

这段代码看起来太通用了。它产生以下输出:

HTTPConnectionPool(host ='wowsucherror',port = 80):URL超过最大重试次数:/(由NewConnectionError(':未能建立新连接:[Errno 11001] getaddrinfo失败',))

我想做的是仅捕获此DNS错误(例如ERR_NAME_NOT_RESOLVED在Chrome中)。作为最后的选择,我只能进行字符串匹配,但是也许有更好,更结构化和前向兼容的方式来处理此错误?

理想情况下,它应该是的DNSError扩展requests

更新:Linux上的错误有所不同。

HTTPConnectionPool(host ='wowsucherror',port = 80):URL超过最大重试次数:/(由NewConnectionError(':导致无法建立新连接:[Errno -2]名称或服务未知',))

将错误报告给requests-> urllib3 https://github.com/shazow/urllib3/issues/1003

UPDATE2:OS X也报告不同的错误。

requests.exceptions.ConnectionError:HTTPConnectionPool(host ='wowsucherror',端口= 80):url超过了最大重试次数:/(由NewConnectionError(':导致:无法建立新连接:[Errno 8]节点名或服务名未提供,或未知',))

ana*_*nik 5

为此,请执行以下操作,但请监控https://github.com/kennethreitz/requests/issues/3630,以找到合适的显示方式。

import requests

def sitecheck(url):
    status = None
    message = ''
    try:
        resp = requests.head('http://' + url)
        status = str(resp.status_code)
    except requests.ConnectionError as exc:
        # filtering DNS lookup error from other connection errors
        # (until https://github.com/shazow/urllib3/issues/1003 is resolved)
        if type(exc.message) != requests.packages.urllib3.exceptions.MaxRetryError:
            raise
        reason = exc.message.reason    
        if type(reason) != requests.packages.urllib3.exceptions.NewConnectionError:
            raise
        if type(reason.message) != str:
            raise
        if ("[Errno 11001] getaddrinfo failed" in reason.message or     # Windows
            "[Errno -2] Name or service not known" in reason.message or # Linux
            "[Errno 8] nodename nor servname " in reason.message):      # OS X
            message = 'DNSLookupError'
        else:
            raise

    return url, status, message

print sitecheck('wowsucherror')
print sitecheck('google.com')
Run Code Online (Sandbox Code Playgroud)