python3 requests 请求https报错: urllib3.exceptions.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:992)

发布时间 2023-11-10 00:44:34作者: BrianSun

正文


代码示例:

#-*- coding:utf-8 -*-
import requests
url = "https://tst.com"
res = requests.get(url=url, verify=False)
print(res.content)

运行就报错:
urllib3.exceptions.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:992)

出现这个问题,百思不得其解。

后来经过对比,发现用urllib3 == 1.26.5可以请求成功,urllib3 == 2.0.7 报错 sslv3 握手失败。所以最少降级 urllib3 的版本是可以解决的,但是终究不是长久之计。

再后来看到了这篇文章:python3.10调用邮件SMTP报错: ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failu..., 发现问题还是出在ssl协议上,可能我要访问的https的服务ssl协议比较老。。(https://bugs.python.org/issue43998

于是借助神奇的chatgpt以及上面的文章,魔改了一个方法,终于访问没问题了。

#-*- coding:utf-8 -*-
import requests
import urllib3
import ssl

# 创建自定义适配器
class TLSAdapter(requests.adapters.HTTPAdapter):
    def init_poolmanager(self, *args, **kwargs):
        context = ssl.create_default_context()
        context.check_hostname = False
        context.set_ciphers("DEFAULT")
        kwargs['ssl_context'] = context
        return super().init_poolmanager(*args, **kwargs)

def request_new_tst(url):
    
    # 创建会话并使用自定义适配器
    session = requests.Session()
    session.mount('https://', TLSAdapter())
    # 发送请求
    response = session.get(url, verify=False)
    print(response.content)

附录


python3 zeep webservice client

#-*- coding:utf-8 -*-
from zeep import Client
from zeep.transports import Transport
import requests
import ssl

# 创建自定义适配器
class TLSAdapter(requests.adapters.HTTPAdapter):
    def init_poolmanager(self, *args, **kwargs):
        context = ssl.create_default_context()
        context.check_hostname = False
        context.set_ciphers("DEFAULT")
        kwargs['ssl_context'] = context
        return super().init_poolmanager(*args, **kwargs)

def zeep_client(url):
    
    session = requests.session()
    session.mount('https://', TLSAdapter())
    session.verify=False
    
    transport = Transport(session=session)
    
    client = Client(wsdl=url, transport=transport)
    print(client)
    
    # 调用wsdl中的方法

if __name__ == "__main__":
    ip = "192.168.2.121"
    url = "https://{0}:123/?wsdl".format(ip)
    zeep_client(url=url)