python请求:请求期间出现SSL错误?

2022-01-25 00:00:00 python python-requests ssl-certificate

问题描述

出于个人兴趣,我正在学习使用 python 请求的 API 请求.我试图简单地下载 URL 'https://live.euronext.com/fr/product/equities/fr0000120578-xpar/'.

I'm learning API requests using python requests for personal interest. I'm trying to simply download the URL 'https://live.euronext.com/fr/product/equities/fr0000120578-xpar/'.

使用 postman 可以完美运行:邮递员 GET 请求截图

It works perfectly using postman : Screenshot of postman GET request

我正在使用此代码在 python 中尝试相同的请求:

I'm trying the same request in python using this code :

    import requests

    headers = {
        "Accept": "text/html,application/xhtml+xml,application/" 
                  "xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "Accept-Encoding": "gzip, deflate",
        "Accept-Language": "en-GB,en;q=0.9,en-US;q=0.8,ml;q=0.7",
        "Connection": "keep-alive",
        "Host": 'live.euronext.com',
        "Upgrade-Insecure-Requests": "1",
        "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) " 
                      "Gecko/20100101 Firefox/75.0"
    }
    url = "https://live.euronext.com/fr/product/equities/fr0000120578-xpar/"
    r = requests.get(url, headers=headers, verify="/etc/ssl/certs/ca-certificates.crt")
    print(r)

我已经阅读了请求文档,我已经搜索了类似的问题,我尝试了各种选项,例如 verify=Falseverify="/etc/ssl/certs/ca-certificates.crt" 指向一些有效的证书.我也尝试了许多标题选项.没有选项有效.我仍然有 [SSL: WRONG_SIGNATURE_TYPE] 错误的签名类型 错误.

I've read the requests doc, i've search for similar issues, i've tried various options like verify=False or verify="/etc/ssl/certs/ca-certificates.crt" pointing to some valid certificates. I've also tried many headers options. None option is working. I still have a [SSL: WRONG_SIGNATURE_TYPE] wrong signature type error.

请帮助我理解这个问题.谢谢,

Please I need help to understand the issue. Thanks,

这是完整的错误文本:

---------------------------------------------------------------------------
SSLError                                  Traceback (most recent call last)
/usr/lib/python3/dist-packages/urllib3/connectionpool.py in urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)
    664             # Make the request on the httplib connection object.
--> 665             httplib_response = self._make_request(
    666                 conn,

/usr/lib/python3/dist-packages/urllib3/connectionpool.py in _make_request(self, conn, method, url, timeout, chunked, **httplib_request_kw)
    375         try:
--> 376             self._validate_conn(conn)
    377         except (SocketTimeout, BaseSSLError) as e:

/usr/lib/python3/dist-packages/urllib3/connectionpool.py in _validate_conn(self, conn)
    995         if not getattr(conn, "sock", None):  # AppEngine might not have  `.sock`
--> 996             conn.connect()
    997 

/usr/lib/python3/dist-packages/urllib3/connection.py in connect(self)
    351 
--> 352         self.sock = ssl_wrap_socket(
    353             sock=conn,

/usr/lib/python3/dist-packages/urllib3/util/ssl_.py in ssl_wrap_socket(sock, keyfile, certfile, cert_reqs, ca_certs, server_hostname, ssl_version, ciphers, ssl_context, ca_cert_dir, key_password)
    369         if HAS_SNI and server_hostname is not None:
--> 370             return context.wrap_socket(sock, server_hostname=server_hostname)
    371 

/usr/lib/python3.8/ssl.py in wrap_socket(self, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, session)
    499         # ctx._wrap_socket()
--> 500         return self.sslsocket_class._create(
    501             sock=sock,

/usr/lib/python3.8/ssl.py in _create(cls, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, context, session)
   1039                         raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
-> 1040                     self.do_handshake()
   1041             except (OSError, ValueError):

/usr/lib/python3.8/ssl.py in do_handshake(self, block)
   1308                 self.settimeout(None)
-> 1309             self._sslobj.do_handshake()
   1310         finally:

SSLError: [SSL: WRONG_SIGNATURE_TYPE] wrong signature type (_ssl.c:1108)

During handling of the above exception, another exception occurred:

MaxRetryError                             Traceback (most recent call last)
/usr/lib/python3/dist-packages/requests/adapters.py in send(self, request, stream, timeout, verify, cert, proxies)
    438             if not chunked:
--> 439                 resp = conn.urlopen(
    440                     method=request.method,

/usr/lib/python3/dist-packages/urllib3/connectionpool.py in urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)
    718 
--> 719             retries = retries.increment(
    720                 method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2]

/usr/lib/python3/dist-packages/urllib3/util/retry.py in increment(self, method, url, response, error, _pool, _stacktrace)
    435         if new_retry.is_exhausted():
--> 436             raise MaxRetryError(_pool, url, error or ResponseError(cause))
    437 

MaxRetryError: HTTPSConnectionPool(host='live.euronext.com', port=443): Max retries exceeded with url: /fr/product/equities/fr0000120578-xpar/ (Caused by SSLError(SSLError(1, '[SSL: WRONG_SIGNATURE_TYPE] wrong signature type (_ssl.c:1108)')))

During handling of the above exception, another exception occurred:

SSLError                                  Traceback (most recent call last)
<ipython-input-2-032056a6c771> in <module>
     13 }
     14 url = "https://live.euronext.com/fr/product/equities/fr0000120578-xpar/"
---> 15 r = requests.get(url, headers=headers, verify="/etc/ssl/certs/ca-certificates.crt")
     16 print(r)

/usr/lib/python3/dist-packages/requests/api.py in get(url, params, **kwargs)
     73 
     74     kwargs.setdefault('allow_redirects', True)
---> 75     return request('get', url, params=params, **kwargs)
     76 
     77 

/usr/lib/python3/dist-packages/requests/api.py in request(method, url, **kwargs)
     58     # cases, and look like a memory leak in others.
     59     with sessions.Session() as session:
---> 60         return session.request(method=method, url=url, **kwargs)
     61 
     62 

/usr/lib/python3/dist-packages/requests/sessions.py in request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
    531         }
    532         send_kwargs.update(settings)
--> 533         resp = self.send(prep, **send_kwargs)
    534 
    535         return resp

/usr/lib/python3/dist-packages/requests/sessions.py in send(self, request, **kwargs)
    644 
    645         # Send the request
--> 646         r = adapter.send(request, **kwargs)
    647 
    648         # Total elapsed time of the request (approximately)

/usr/lib/python3/dist-packages/requests/adapters.py in send(self, request, stream, timeout, verify, cert, proxies)
    512             if isinstance(e.reason, _SSLError):
    513                 # This branch is for urllib3 v1.22 and later.
--> 514                 raise SSLError(e, request=request)
    515 
    516             raise ConnectionError(e, request=request)

SSLError: HTTPSConnectionPool(host='live.euronext.com', port=443): Max retries exceeded with url: /fr/product/equities/fr0000120578-xpar/ (Caused by SSLError(SSLError(1, '[SSL: WRONG_SIGNATURE_TYPE] wrong signature type (_ssl.c:1108)')))


解决方案

终于找到问题了,感谢https://github.com/psf/requests/issues/4775

import requests
import ssl
from urllib3 import poolmanager

url = 'https://live.euronext.com/fr/product/equities/FR0000120271-XPAR'

class TLSAdapter(requests.adapters.HTTPAdapter):

    def init_poolmanager(self, connections, maxsize, block=False):
        """Create and initialize the urllib3 PoolManager."""
        ctx = ssl.create_default_context()
        ctx.set_ciphers('DEFAULT@SECLEVEL=1')
        self.poolmanager = poolmanager.PoolManager(
                num_pools=connections,
                maxsize=maxsize,
                block=block,
                ssl_version=ssl.PROTOCOL_TLS,
                ssl_context=ctx)

session = requests.session()
session.mount('https://', TLSAdapter())
res = session.get(url)
print(res)

输出是 <Response [200]>

相关文章