Python中出现SSL: CERTIFICATE_VERIFY_FAILED错误

错误

当使用urllib模块中的urlopen()时,出现URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)>错误

原因

Windows系统上(其他系统未知)Python在request的时候不会去查看系统证书

故没有通过ssl证书检查 以下提供两种解决方案

解决方法1

导入ssl库,使用SSLContext()创建一个context

然后在使用urlopen函数时带上context=参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from urllib import request
import ssl

req = request.Request('https://frnks.top')
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36')

mycontext = ssl.SSLContext() #创建context
with request.urlopen(req,context=mycontext) as f:
# 下文与本文无关
data = f.read()
print('Status:', f.status,f.reason)
for k, v in f.getheaders():
print(f'{k}:{v}')
decoded = data.decode('utf-8')
with open('/Users/frnks/test.html','w',encoding='utf-8') as f: #这里open时就要加上encoding 不然默认以系统编码gbk写入
f.write(decoded)
print('Data:', decoded)

注意

这样其实并没有解决ssl证书的问题 只是单纯避过了而已

解决方法2

终端中输入pip install certifi安装certifi

用于验证 SSL 证书的可信度,同时验证 TLS 主机的身份。

使用其中的where()函数找到系统ssl证书 并在urlopen()中添加参数cafile=

1
2
3
4
import urllib.request as urlrq
import certifi

resp = urlrq.urlopen('https://example.com/bar/baz.html',cafile=certifi.where())

不过就我的电脑来说,安装完这个库似乎就可以直接通过ssl检查了