在Python3.6.5中,请求获得SSL证书错误

时间:2019-02-22 14:56:06

标签: web-scraping python-requests python-3.6 scrapy-spider python-requests-html

我曾尝试使用请求获取以下URL,但遇到SSL证书错误。我已经尝试了所有较早的堆栈溢出查询,但是似乎没有任何作用 代码:

resp = requests.get('https://www.magidglove.com/', verify=certifi.where())

我给了verify = False,仍然无法正常工作

错误:

    raise MaxRetryError(_pool, url, error or ResponseError(cause))urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='www.magidglove.com', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",),))

2 个答案:

答案 0 :(得分:0)

可以通过在Python代码中添加导入ssl并添加verify=ssl.CERT_NONE来轻松解决此问题,因此您的代码应如下所示:

import requests
import ssl

resp = requests.get('https://www.magidglove.com/', verify=ssl.CERT_NONE)

也就是说,在运行此代码时,您可能会遇到此错误:

  

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connectionpool.py:858:InsecureRequestWarning:发出未经验证的HTTPS请求。强烈建议添加证书验证。参见:https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings

您可以通过在代码中添加以下几行来禁用它:

import requests
import ssl
import urllib3
urllib3.disable_warnings()
resp = requests.get('https://www.magidglove.com/', verify=ssl.CERT_NONE)

希望这会有所帮助!

答案 1 :(得分:0)

TL; DR-服务器配置错误。修复服务器,通过verify=ssl.CERT_NONE或明确下载并通过www.magidglove.com的证书。

问题出在服务器上,而不是客户端上。服务器仅配置为返回自己的证书,这不足以使客户端信任它。服务器通常需要配置为返回完整的证书链。

为了进行诊断,可以使用openssl查看有关返回的证书链的一些原始信息:

$ openssl s_client -connect www.google.com:443 -showcerts -servername www.google.com

CONNECTED(00000003)
depth=2 OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign
verify return:1
depth=1 C = US, O = Google Trust Services, CN = Google Internet Authority G3
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google LLC, CN = www.google.com
verify return:1
... snipped the rest of the output ...

您可以看到服务器返回了3个证书,并且以相反的顺序对其进行了验证。 certifi库信任GlobalSign证书,depth=1处的证书由depth=2处的证书创建,最后一个证书CN=www.google.com由该证书创建在depth=1

现在,我们将其与您尝试连接的服务器进行比较:

$ openssl s_client -connect www.magidglove.com:443 -showcerts -servername www.magidglove.com

CONNECTED(00000003)
depth=0 businessCategory = Private Organization, jurisdictionC = US, jurisdictionST = Illinois, serialNumber = 00043176, C = US, ST = Illinois, L = Romeoville, O = "Magid Glove and Safety Manufacturing Company, L.L.C.", OU = web site, CN = www.magidglove.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 businessCategory = Private Organization, jurisdictionC = US, jurisdictionST = Illinois, serialNumber = 00043176, C = US, ST = Illinois, L = Romeoville, O = "Magid Glove and Safety Manufacturing Company, L.L.C.", OU = web site, CN = www.magidglove.com
verify error:num=21:unable to verify the first certificate
verify return:1

您可以从此输出中看到一些信息: -服务器仅返回了一个证书 -客户端尝试验证证书,但不能

需要ssl的一些知识才能知道无法验证的原因是它不信任证书,但是现在我们知道了,我们可以看到让服务器返回完整的证书链会解决它。我怀疑chrome和其他浏览器未报告错误的原因是浏览器本身了解DigiCert,因此不需要完整的链。