断开VPN时使用Python Zeep库出现SSL握手失败错误
Python Zeep库SSL握手失败问题求助
未连接公司VPN时运行代码,抛出以下SSL错误:
requests.exceptions.SSLError: HTTPSConnectionPool(host='ws-gateway-cert.xxx.com', port=443): Max retries exceeded with url: /services (Caused by SSLError(SSLError(1, '[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1007)')))
连接VPN后代码可正常运行,但Postman、SoapUI等客户端无需VPN就能成功发起相同请求。我的代码如下:
session = Session() session.trust_env = False session.mount('https://', Pkcs12Adapter( pkcs12_filename=r'C:\PROJECT\assets\cert.p12', pkcs12_password='****')) session.verify = False transport = Transport(session=session, ) settings = Settings(strict=False, xml_huge_tree=True, xsd_ignore_sequence_order=True, force_https=False) self.vw_client = Client( wsdl=self.wsdl, transport=transport, plugins=[WsAddressingPlugin(address_url='ws://address'), # LoggingPlugin() ], settings=settings )
可能的解决方案
1. 检查代理配置
Postman默认会使用系统代理,而你的代码设置了session.trust_env=False,会忽略系统代理设置。如果公司网络下访问目标服务器需要通过内部代理(无需VPN),可以尝试:
- 移除
session.trust_env=False,让requests自动使用系统代理; - 或者手动指定代理:
proxies = { 'https': 'http://your-company-proxy:port' # 替换为公司实际代理地址 } session.proxies.update(proxies)
2. 指定SSL协议版本
服务器可能只支持特定的SSL/TLS版本,而requests默认禁用了旧版本。可以通过自定义适配器强制指定协议版本:
from requests.adapters import HTTPAdapter from urllib3.poolmanager import PoolManager import ssl class CustomPkcs12Adapter(Pkcs12Adapter): def init_poolmanager(self, *args, **kwargs): kwargs['ssl_version'] = ssl.PROTOCOL_TLSv1_2 # 或尝试ssl.PROTOCOL_TLSv1_3 return super().init_poolmanager(*args, **kwargs) # 替换原适配器 session.mount('https://', CustomPkcs12Adapter( pkcs12_filename=r'C:\PROJECT\assets\cert.p12', pkcs12_password='****'))
3. 匹配服务器支持的加密套件
服务器可能只接受特定加密套件,而requests默认套件列表不包含。可以从Postman的请求详情中查看服务器使用的加密套件,然后在适配器中指定:
class CustomPkcs12Adapter(Pkcs12Adapter): def init_poolmanager(self, *args, **kwargs): kwargs['ssl_version'] = ssl.PROTOCOL_TLSv1_2 kwargs['ciphers'] = 'ECDHE-RSA-AES256-GCM-SHA384' # 替换为Postman中看到的套件 return super().init_poolmanager(*args, **kwargs)
4. 验证证书链(可选)
即使设置了session.verify=False,部分环境下服务器证书链可能无法自动获取。可以尝试指定CA证书路径:
session.verify = 'path/to/company-ca-bundle.crt'
内容的提问来源于stack exchange,提问作者Omid Erfanmanesh
相关产品推荐
相关产品推荐

