某些特定網站在SSL通信過程中的TLS版本和加密算法的選擇,導致使用較高版本 requests 時產生 SSL: SSLV3_ALERT_HANDSHAKE_FAILURE的錯誤。根據HTTPS 服務的TLS版本支持情況可強制使用1.1 1.2等。按照一般經驗,大部分都支持 1.2, 所以示例代碼中使用1.2。
tips: 該方案不適用所有此類報錯,請多嘗試。
import ssl
import requests
from requests.adapters import HTTPAdapter
class SSLAdapter(HTTPAdapter):
def init_poolmanager(self, *args, **kwargs):
"""
tls1.3 不再支持RSA KEY exchange,py3.10 增加TLS的默認安全設置。可能導致握手失敗。
使用 `ssl_context.set_ciphers('DEFAULT')` DEFAULT 老的加密設置。
"""
ssl_context = ssl.create_default_context()
ssl_context.set_ciphers('DEFAULT')
ssl_context.check_hostname = False # 避免在請求時 verify=False 設置時報錯, 如果設置需要校驗證書可去掉該行。
ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2 # 最小版本設置成1.2 可去掉低版本的警告
ssl_context.maximum_version = ssl.TLSVersion.TLSv1_2 # 最大版本設置成1.2
kwargs["ssl_context"] = ssl_context
return super().init_poolmanager(*args, **kwargs)
sess = requests.session()
sess.mount("https://", SSLAdapter()) # 將上面定義的SSLAdapter 應用起來
resp = sess.get("your url")