2016-10-20 36 views
0

我想用python-requests來檢查過期的域名。準確地捕捉到與Python請求的DNS錯誤

import requests 

try: 
    status = requests.head('http://wowsucherror') 
except requests.ConnectionError as exc: 
    print(exc) 

此代碼看起來過於通用。它產生的輸出如下:

HTTPConnectionPool(host='wowsucherror', port=80): Max retries exceeded with url:/(Caused by NewConnectionError(': Failed to establish a new connection: [Errno 11001] getaddrinfo failed',))

我希望做的是隻捕獲這個DNS錯誤(如ERR_NAME_NOT_RESOLVED在Chrome)。作爲最後的手段,我可​​以做字符串匹配,但也許有更好,更結構化和前向兼容的方式來處理這個錯誤?

理想情況下,它應該是一些DNSError擴展到requests

UPDATE:Linux上的錯誤是不同的。

HTTPConnectionPool(host='wowsucherror', port=80): Max retries exceeded with url:/(Caused by NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known',))

報告的bug到requests - >urllib3https://github.com/shazow/urllib3/issues/1003

UPDATE2:OS X還報告不同的錯誤。

requests.exceptions.ConnectionError: HTTPConnectionPool(host='wowsucherror', port=80): Max retries exceeded with url:/(Caused by NewConnectionError(': Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known',))

+1

我想你會被卡住解析字符串中的錯誤號,插座錯誤抓到這裏來https://github.com/kennethreitz/requests/blob/master/requests/packages/urllib3/connection.py #L149但沒有errno屬性設置在任何地方,所以你得到的只是錯誤信息。如果你只是檢查e.errno,你實際上可以訪問'e'。 –

+0

@PadraicCunningham它也看起來像它不是跨平臺的錯誤消息,我需要知道它在Linux和OS X上的外觀。 –

+0

確實,它在我的Ubuntu盒子上拋出了[errno -2],我試過'除了(NewConnectionError,socket.error)爲exc:'但套接字錯誤被吞噬了。可能值得開始一個問題,因爲它似乎是一個合理的事情要做,這只是一個傳遞e.errno的問題。 –

回答

2

用這個黑客做到了這一點,但請監視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')