Python urllib和“SSL:CERTIFICATE_VERIFY_FAILED”错误
在本文中,我们将介绍Python的urllib库以及常见的“SSL:CERTIFICATE_VERIFY_FAILED”错误。
阅读更多:Python 教程
什么是urllib库?
Python的urllib库提供了一组操作URL的功能,包括发送HTTP请求、处理响应等。它是Python标准库中的一部分,因此无需安装额外的模块就可以使用。
SSL:CERTIFICATE_VERIFY_FAILED错误
在使用urllib发送HTTPS请求时,可能会遇到“SSL:CERTIFICATE_VERIFY_FAILED”错误。这是因为urllib默认会验证服务器的SSL证书,而如果证书不可信或已过期,会引发该错误。
为了解决这个问题,我们可以在urllib请求之前禁用证书验证。以下是一个示例:
import urllib.request
import ssl
context = ssl._create_unverified_context()
response = urllib.request.urlopen(url, context=context)
上述代码中,我们通过ssl._create_unverified_context()
方法创建了一个未验证的SSL上下文对象,并在发送请求时传递了这个上下文对象。这样就可以跳过对证书的验证,解决了“SSL:CERTIFICATE_VERIFY_FAILED”错误。
验证证书
尽管禁用证书验证能够解决“SSL:CERTIFICATE_VERIFY_FAILED”错误,但这也意味着我们无法确保服务器的身份和数据的安全性。为了确保安全,我们应该验证服务器的证书。
Python的ssl模块提供了许多函数来验证证书,包括验证证书的有效性、主机名匹配等。我们可以使用这些函数来手动验证服务器证书,或者使用第三方库,如certifi。以下是一个使用certifi验证证书的示例代码:
import urllib.request
import ssl
import certifi
context = ssl.create_default_context(cafile=certifi.where())
response = urllib.request.urlopen(url, context=context)
上述代码中,我们通过ssl.create_default_context()
方法创建了一个默认的SSL上下文对象,并将certifi的证书路径传递给cafile
参数。这样就可以使用certifi库提供的证书验证功能来验证服务器证书。
忽略主机名验证
除了证书验证外,urllib还进行了主机名验证。如果服务器的主机名与证书中的主机名不匹配,会引发“SSL:CERTIFICATE_VERIFY_FAILED”错误。如果我们确定服务器的主机名是正确的,可以通过以下方法忽略主机名验证:
import urllib.request
import ssl
context = ssl._create_unverified_context()
ssl.match_hostname = lambda cert, hostname: True
response = urllib.request.urlopen(url, context=context)
上述代码中,我们将ssl.match_hostname
函数重写为始终返回True,这样就可以忽略主机名验证。不过,这也意味着我们无法确保与服务器通信的安全性。
总结
本文介绍了Python的urllib库以及常见的“SSL:CERTIFICATE_VERIFY_FAILED”错误。我们可以通过禁用证书验证、手动验证证书或使用第三方库来解决这个错误。然而,为了确保通信的安全性,我们还是应该验证服务器的证书,并尽量避免忽略主机名验证。