Reputation: 455
I'm using urllib.request.urlretrieve to download a file to local.
urllib.request.urlretrieve(url_string,file_name)
It throws error:
ssl.CertificateError was unhandled by user code Message: hostname 'foo.net' doesn't match either of 'a248.e.akamai.net', '.akamaihd.net', '.akamaihd-staging.net', '.akamaized.net', '.akamaized-staging.net'
If you copy the url into Chrome, it will show you a notification and you need to say something like "keep going to the url".
Upvotes: 25
Views: 75992
Reputation: 7123
Function urllib.request.urlretrieve
doesn't accept any SSL options but urllib.request.urlopen
does.
However instead creating a secure SSL context with ssl.create_default_context()
and making it insecure you can create an insecure context with ssl.SSLContext()
:
This:
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
is equivalent to:
ctx = ssl.SSLContext()
(For Python < 3.5.3 use ssl.SSLContext(ssl.PROTOCOL_TLSv1)
)
Which makes a nice one-liner:
import ssl
import urllib.request
with urllib.request.urlopen("https://wrong.host.badssl.com/", context=ssl.SSLContext()) as url:
print(url.read())
Upvotes: 7
Reputation: 369134
Use urllib.request.urlopen
with custom ssl context:
import ssl
import urllib.request
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
with urllib.request.urlopen(url_string, context=ctx) as u, \
open(file_name, 'wb') as f:
f.write(u.read())
Alternatively, if you use requests
library, it could be simpler:
import requests
with open(file_name, 'wb') as f:
resp = requests.get(url_string, verify=False)
f.write(resp.content)
Upvotes: 56