我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python urllib3和requests发送HTTPS请求时出现SSLError或InsecureRequestWarning

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python urllib3和requests发送HTTPS请求时出现SSLError或InsecureRequestWarning

目录

问题及原因分析

在我们通过urllib3和requests进行HTTPS请求时,可能会出现SSLError的错误:
示例1 找不到对应的本地证书

Caused by SSLError(SSLCertVerificationError(1,'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate

示例2 服务端证书过期

Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired

SSL为安全套接层,是HTTPS的安全基础。当证书验证失败,urlib3和requests就会抛出SSL错误。
为什么证书会验证失败?这里要先说清楚HTTPS中证书的工作原理:

公钥证书,是服务端提前向第三方机构申请颁发的,由公钥和数字签名组成。服务端提供公钥,第三方机构则负责对公钥做数字签名(即用第三方机构私钥对服务端的公钥加密)。
在HTTPS请求中,服务端会将自己的公钥证书发送给客户端,客户端拿到公钥证书后,需要凭借第三方机构的公钥(也称为证书,一般会自带在操作系统或浏览器中)去验证数字签名的有效性,验证通过即可确认服务端公钥为真实有效,然后通过公钥进行安全的加密通信。

因此,证书验证失败,就是请求方无法验证服务端公钥证书的有效性,有两种原因:
1.本地缺少对应第三方机构的公钥(也称为第三方机构的证书)
2.服务端的公钥证书有误,可能已过期
第二种原因来自服务端,我们作为请求方无法解决,只能通过后面提到的方法忽略警告或不使用SSL层。
第一种则可通过下面的方法解决。

优先考虑的解决方法:

下载证书

urllib3和requests在发送https请求时都会加载默认的系统证书,但更可靠的方法是安装 Mozilla 提供的证书包。
可以直接到官方网站去下载,但更推荐安装certifi包,方便以后更新:

python -m pip install certifi

安装后可以通过certifi的方法查询证书路径

>>> import certifi>>> certifi.where()'F:\Anaconda\lib\site-packages\certifi\cacert.pem'

使用证书

urlib3:

指定证书路径创建连接池:

http = urllib3.PoolManager(    cert_reqs='CERT_REQUIRED',  //默认值,指证书必须验证通过,否则抛出SSL错误    ca_certs=certifi.where()   //指定证书路径)

连接池会使用指定路径的证书,并在验证失败时抛出异常:

http.request('GET', 'https://google.com')(No exception)http.request('GET', 'https://expired.badssl.com')urllib3.exceptions.SSLError ...

requests:

跟urblib3类似,只是指定证书方式有不同,通过verify参数来指定(路径也可以直接用文件的绝对路径):

requests.get('https://github.com', verify='F:\Anaconda\lib\site-packages\certifi\cacert.pem')

或者通过session全局指定:

s = requests.Session()s.verify = 'F:\Anaconda\lib\site-packages\certifi\cacert.pem's.get('https://github.com')(No exception)s.get('https://expired.badssl.com')urllib3.exceptions.SSLError ...

手动获取证书

如果仍然请求失败,但浏览器能正常访问,那可以直接从浏览器导出证书来使用。以谷歌浏览器为例:
1.按顺序导出证书
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
2.导出文件后,将文件中的公钥复制到指定的证书路径中即可在这里插入图片描述

不推荐使用的备用解决方法:

强烈建议不要发出未经验证的 HTTPS 请求,因为HTTPS可以防止中间人攻击(窃听,伪装,篡改等问题)。但如果确实无法解决证书问题,那可以关闭HTTPS请求中的SSL验证,来解决该问题。

关闭方法

urllib3:
指定cert_reqs为CERT_NONE(默认为CERT_REQUIRED)

http = urllib3.PoolManager(    cert_reqs = 'CERT_NONE')

requests:
指定verify为False(默认为True)

#单次关闭requests.get('https://expired.badssl.com', verify=False)<Response [200]>#全局关闭s = requests.Session()s.verify = False

也可以通过SSL包来关闭(urllib3和requests通用)

import sslssl._create_default_https_context = ssl._create_unverified_context

衍生问题

关闭后便可以正常请求,但是会弹出InsecureRequestWarning的警告

InsecureRequestWarning: Unverified HTTPS request is being made to host 'www.xxx.com'.Adding certificate verification is strongly advised

如果了解风险并希望禁用这些警告,可以使用以下方法(urllib3和requests通用):

import urllib3urllib3.disable_warnings()

或者也可以使用logging标准模块捕获警告:

logging.captureWarnings(True)

最后,还可以通过设置环境变量PYTHONWARNINGS来限制该级别的警告 。

另外,上述方法也会同时禁用下列警告:
InsecurePlatformWarning
这发生在具有过时ssl模块的 Python 2 平台上。这些较旧的ssl模块可能会导致一些不安全的请求在它们应该失败的时候成功,而安全的请求则会在它们应该成功的地方失败
SNIMissingWarning
这发生在早于 2.7.9 的 Python 2 版本上。这些旧版本缺乏SNI支持。这可能会导致服务器提供客户端认为无效的证书
这两个警告对应问题的解决方法可以去官网文档查看

参考文档

urllib3: https://urllib3.readthedocs.io/en/1.26.x/user-guide.html#
request:https://requests.readthedocs.io/en/latest/user/advanced/

来源地址:https://blog.csdn.net/weixin_40773848/article/details/126719313

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python urllib3和requests发送HTTPS请求时出现SSLError或InsecureRequestWarning

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录