So if you want to be prepared for$_{HTTPError}$ or$_{URLError}$ there are two basic approaches. I prefer the second approach. Number 1 3.3 Wrapping it Up from urllib.request import Request, urlopen from urllib.error import URLError, HTTPError req =Request(someurl) try : response =urlopen(req) except HTTPError as e: print('The server couldn \' t fulfill the request. ') print('Error code:', e.code) except URLError as e: print('We failed to reach a server. ') print('Reason:', e.reason) else : # everything is fine from urllib.request import Request, urlopen from urllib.error import URLError req =Request(someurl) try : response =urlopen(req) except URLError as e: if hasattr(e,'reason'): print('We failed to reach a server. ') print('Reason:', e.reason) elif hasattr(e,'code'): print('The server couldn \' t fulfill the request. ') print('Error code:', e.code) else : # everything is fine 4 info and geturl Number 2 Note: The except HTTPError must come first, otherwise except URLError will also catch an HTTPError . The response returned by urlopen (or the$_{HTTPError}$ instance) has two useful methods$_{info()}$ and$_{geturl()}$ and is defined in the module$_{urllib.response}$ .. geturl - this returns the real URL of the page fetched. This is useful because$_{urlopen}$(or the opener object used) may have followed a redirect. The URL of the page fetched may not be the same as the URL requested. info - this returns a dictionary-like object that describes the page fetched, particularly the headers sent by the server. It is currently an$_{http.client.HTTPMessage}$ instance. Typical headers include ‘Content-length’, ‘Content-type’, and so on. See the Quick Reference to HTTP Headers for a useful listing of HTTP headers with brief explanations of their meaning and use. 7