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

这篇具有很好参考价值的文章主要介绍了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.按顺序导出证书
Python urllib3和requests发送HTTPS请求时出现SSLError或InsecureRequestWarningPython urllib3和requests发送HTTPS请求时出现SSLError或InsecureRequestWarning
Python urllib3和requests发送HTTPS请求时出现SSLError或InsecureRequestWarning
2.导出文件后,将文件中的公钥复制到指定的证书路径中即可Python urllib3和requests发送HTTPS请求时出现SSLError或InsecureRequestWarning

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

强烈建议不要发出未经验证的 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 ssl
ssl._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 urllib3
urllib3.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://www.toymoban.com/news/detail-405772.html

到了这里,关于Python urllib3和requests发送HTTPS请求时出现SSLError或InsecureRequestWarning的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【解决】selenium和requests中urllib3版本冲突

    selenium要求urllibs版本为1.26,requests要求urllibs版本1.25,=1.21. 升级requests版本为最新版,就可以兼容。 在conda中安装selenium报错,urllib3版本出现错误。 然后安装selenium 成功 查看selenium版本号 pip show selenium

    2024年02月11日
    浏览(62)
  • 【已解决】requests 和 selenium对 Urllib3版本冲突

    requests对urllib3要求版本低于1.23,而selenium要求urllib3高于1.26,直接用pip install requests安装的版本是旧的(1.20),最新的为1.28,同时会把你新版本的urllib3删掉,换成1.23,于是无限死循环。。 解决办法:下载最新版的requests 下载链接:https://pypi.org/project/requests/#files 随后一番解压

    2024年02月11日
    浏览(58)
  • Python3中urllib请求网页报错(AttributeError: module ‘urllib‘ has no attribute ‘request‘)

    报错代码 python3.8,想用urllib库请求访问贴吧,报错代码如下: 报错信息:看到两个request亮着,说明有问题   运行后的报错 报错内容翻译: 属性错误:模块urllib模块没有属性request 报错原因: Python中出现AttributeError的错误主要有两类原因: 1. 没有引入对应正确的包 2. 工程目

    2024年02月15日
    浏览(40)
  • python requests请求报错Caused by SSLError(SSLCertVerificationError(1, ‘[SSL: CERTIFICATE_VERIFY_FAILED]

    解决方案如下: requests请求时关闭ssl验证即可 添加参数 verify=False

    2024年01月23日
    浏览(52)
  • 【python】(十九)python常用第三方库——urllib3

    官方文档:https://urllib3.readthedocs.io/en/stable/ Urllib3是一个功能强大,条理清晰,用于HTTP客户端的Python库,许多Python的原生系统已经开始使用urllib3。Urllib3提供了很多python标准库里所没有的重要特性: 线程安全 连接池管理 客户端 SSL/TLS 验证 支持 HTTP 和 SOCKS 代理 …… 通过 pip

    2024年02月13日
    浏览(83)
  • python 模块urllib3 HTTP 客户端库

    官网文档地址:https://urllib3.readthedocs.io/en/stable/reference/index.html 一、安装 二、基本使用 三、urllib3.request() 发送请求 四、urllib3.PoolManager() 创建和管理连接池,以便在发送多个 HTTP 请求时重用连接 http.request(method,url,body,fields,headers) 发送请求 method(字符串):指定请求的 HTTP 方

    2024年02月11日
    浏览(50)
  • python 模块requests 发送 HTTP 请求

    一、简介 requests 模块是 python 基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库。它比 urllib 更加方便,可以节约我们大量的工作 二、安装 三、方法 requsts.requst(method, url,headers,cookies,proxies,timeout) method:请求方式;字符串类型 url:请求的地址;字符串类型 params:查询参数,g

    2024年02月11日
    浏览(42)
  • Python+Requests模拟发送post请求

    发送post请求的基础知识dumps和loads 代码示例: 以微信开放平台举例 发送post请求 查看执行结果:  上传文件 查看执行结果  封装post请求 代码示例: 封装main方法 代码示例: 封装测试类 示例代码: 光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用

    2024年02月07日
    浏览(48)
  • Python+Requests模拟发送GET请求

    前置条件: 导入requests库 一、发送不带参数的get请求 代码如下: 以百度首页为例 二、发送带参数的get请求 发送带参数的get请求有几种方式 方式一:参数在URL中 代码如下: 以百度首页为例 方式二:参数在字典中 代码如下: 以百度首页为例 获取响应数据的基本信息 代码如

    2024年01月20日
    浏览(48)
  • Python爬虫requests判断请求超时并重新post/get发送请求

    在上面的示例中,send_request_get函数接受一个URL作为参数,并可选地指定最大重试次数和超时时间。函数使用 requests.get 发送GET请求,并设置了超时时间为5秒。如果请求超时,会捕获 requests.exceptions.Timeout 异常,并输出重试信息。如果发生其他异常,会捕获 requests.exceptions.Req

    2024年02月11日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包