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

使用Python请求精确捕获DNS错误,dns,python-requests,Dns,Python Requests,我正在尝试使用python请求检查过期域名 import requests try: status = requests.head('http://wowsucherror') except requests.ConnectionError as exc: print(exc) 这段代码看起来太泛化了。它产生以下输出: HTTPConnectionPool(host='wowsucherro',port=80):url:/(由NewConnectionError(':建立新连

我正在尝试使用
python请求检查过期域名

import requests

try:
    status = requests.head('http://wowsucherror')
except requests.ConnectionError as exc:
    print(exc)
这段代码看起来太泛化了。它产生以下输出:

HTTPConnectionPool(host='wowsucherro',port=80):url:/(由NewConnectionError(':建立新连接失败:[Errno 11001]getaddrinfo失败',)引起的)超过了最大重试次数

我想做的是只捕获这个DNS错误(比如Chrome中的
ERR\u NAME\u NOT\u RESOLVED
)。作为最后的手段,我可以只做字符串匹配,但也许有更好的、更结构化的和前向兼容的方法来处理这个错误

理想情况下,它应该是对
请求的一些
DNSError
扩展

更新:Linux上的错误不同

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

请求报告的bug
->
urllib3

更新2:OS X还报告不同的错误

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


使用此黑客完成此操作,但请监视以获得正确的显示方式

导入请求
def站点检查(url):
状态=无
消息=“”
尝试:
resp=requests.head('http://'+url)
状态=str(相应的状态代码)
除请求外。作为exc的ConnectionError:
#从其他连接错误中筛选DNS查找错误
#(直到https://github.com/shazow/urllib3/issues/1003 (已解决)
如果类型(exc.message)!=requests.packages.urllib3.exceptions.MaxRetryError:
提升
原因=exc.message.reason
如果类型(原因)!=requests.packages.urllib3.exceptions.NewConnectionError:
提升
如果类型(原因消息)!=str:
提升
如果reason.message或#Windows中的(“[Errno 11001]getaddrinfo失败”
reason.message或#Linux中的“[Errno-2]名称或服务未知”
原因消息中的“[Errno 8]nodename或servname:#OS X
消息='DNSLookupError'
其他:
提升
返回url、状态、消息
打印站点检查('wowsucherror')
打印站点检查('google.com')

使用此黑客完成此操作,但请监视是否有正确的显示方式

导入请求
def站点检查(url):
状态=无
消息=“”
尝试:
resp=requests.head('http://'+url)
状态=str(相应的状态代码)
除请求外。作为exc的ConnectionError:
#从其他连接错误中筛选DNS查找错误
#(直到https://github.com/shazow/urllib3/issues/1003 (已解决)
如果类型(exc.message)!=requests.packages.urllib3.exceptions.MaxRetryError:
提升
原因=exc.message.reason
如果类型(原因)!=requests.packages.urllib3.exceptions.NewConnectionError:
提升
如果类型(原因消息)!=str:
提升
如果reason.message或#Windows中的(“[Errno 11001]getaddrinfo失败”
reason.message或#Linux中的“[Errno-2]名称或服务未知”
原因消息中的“[Errno 8]nodename或servname:#OS X
消息='DNSLookupError'
其他:
提升
返回url、状态、消息
打印站点检查('wowsucherror')
打印站点检查('google.com')

您可以使用较低级别的网络接口,
socket.getaddrinfo


您可以使用较低级别的网络接口,
socket.getaddrinfo


我有一个基于前面答案的函数,它似乎不再工作了。此函数根据解析和请求来检查url的“活跃度”。ok
函数不仅仅针对解析错误,而且可以轻松调整以适应

def check_live(url):
    try:
        r = requests.get(url)
        live = r.ok
    except requests.ConnectionError as e:
        if 'MaxRetryError' not in str(e.args) or 'NewConnectionError' not in str(e.args):
            raise
        if "[Errno 8]" in str(e) or "[Errno 11001]" in str(e) or ["Errno -2"] in str(e):
            print('DNSLookupError')
            live = False
        else:
            raise
    except:
        raise
    return live

我有一个基于前面答案的函数,它似乎不再工作了。此函数根据解析和请求来检查url的“活跃度”。ok
函数不仅仅针对解析错误,而且可以轻松调整以适应

def check_live(url):
    try:
        r = requests.get(url)
        live = r.ok
    except requests.ConnectionError as e:
        if 'MaxRetryError' not in str(e.args) or 'NewConnectionError' not in str(e.args):
            raise
        if "[Errno 8]" in str(e) or "[Errno 11001]" in str(e) or ["Errno -2"] in str(e):
            print('DNSLookupError')
            live = False
        else:
            raise
    except:
        raise
    return live

我认为您将无法解析字符串中的errno,这里捕获了套接字错误,但没有设置errno属性,因此您得到的只是错误消息。如果你真的有权访问
e
如果你只是想检查一下e.errno.@PadraicCunningham它看起来也像是一条错误消息,它不是跨平台的,我需要知道它在Linux和OS X上是什么样子。事实上,它在我的Ubuntu框上抛出了一个[errno-2],我尝试了
除了(NewConnectionError,socket.error)作为exc:
但是套接字错误被吞没了。可能值得开始一个问题,因为这似乎是一件合理的事情,只需传递e.errno即可。我认为您将无法从字符串解析errno,套接字错误在此处被捕获,但没有设置errno属性,因此您得到的只是错误消息。如果你真的有权访问
e
如果你只是想检查一下e.errno.@PadraicCunningham它看起来也像是一条错误消息,它不是跨平台的,我需要知道它在Linux和OS X上是什么样子。事实上,它在我的Ubuntu框上抛出了一个[errno-2],我尝试了
除了(NewConnectionError,socket.error)作为exc:
但是套接字错误被吞没了。可能值得开始一个问题,因为这似乎是一个合理的事情想做,这将只是一个传递e.errno的问题。