使用requests
做爬虫(目标站点为 https 站点)时遇到以下问题:
先贴上伪代码
response = requests.get(url=self.url, headers=self.headers, params=self.params,
proxies={"https": self.get_proxy()}, timeout=5, verify=False)
现在的情况是
<class 'requests.exceptions.SSLError'> HTTPSConnectionPool(host='xxxx.com', port=443):
Max retries exceeded with url: xxxx.com
(Caused by SSLError(SSLError("bad handshake: Error
([('SSL routines', 'ssl3_get_record', 'wrong version number')],)",),))
网站在 chrome 上右上角具有绿色安全标识
查找资料后
CA_BUNDLE
文件或者具有CA 证书
的目录。client side certificate
),可以是如下形式。# 设置`CA_BUNDLE`文件
requests.get('https://github.com', verify='/path/to/certfile')
# 指定一个本地证书作为客户端证书
requests.get('https://kennethreitz.org', cert=('/path/client.cert', '/path/client.key'))
requests.get('https://kennethreitz.org', cert='/path/client.cert')
参考链接: http://www.python-requests.org/en/latest/user/advanced/#ssl-cert-verification
requests 源码对 verify 和 cert 参数的注释
:param verify: (optional) Either a boolean,in which case it controls whether we verify
the server's TLS certificate, or a string,in which case it must be a path to a CA bundle
to use. Defaults to ``True``.
:param cert: (optional) if String, path to ssl client cert file (.pem).
If Tuple, ('cert', 'key') pair.
不理解的问题
CA_BUNDLE
文件或CA 证书
是否就是第三方机构颁发的具有数字签名的证书?在什么情况下需要自己指定,如何获取此文件呢?ssl client cert file
客户端证书文件的作用是什么?如何获取?爬虫过程中需要自己指定吗?对问题 3 的猜测
接下来的动作
如果您能看到这里,真的非常感谢
如果各位老哥有了解或遇到过类似的问题可以帮忙一起讨论,灰常谢谢!
补充一下我了解和分析得出的结论(关于requests的verify和cert参数):
在stackoverflow上看到,requests安装有两种方式:
2.1 会额外安装三个lib
2.2. 作用
Using these packages as opposed to the default standard library options will allow for more secure SSL connections.
使用此方式会允许更加安全的SSL链接。
Also by default requests can't connect to some sites on OSX because of ancient OpenSSL. Using the above 3 packages makes it possible. (Donald Stufft)
默认情况下,请求无法连接到的某些使用了老版本OpenSSL协议的站点,使用上述3个软件包即可连接。
在Python 3.4+ 和 Python 2.7.9+版本中可能不需要。
参考链接1:https://stackoverflow.com/questions/31811949/pip-install-requestssecurity-vs-pip-install-requests-difference
参考链接2:https://stackoverflow.com/questions/29099404/ssl-insecureplatform-error-when-using-requests-package
1
rrfeng 2018-03-08 18:36:16 +08:00 via Android
爬虫建议直接不验证证书
客户端证书不需要。 |
2
rrfeng 2018-03-08 18:36:56 +08:00 via Android
不是 SSL 版本问题吗?还 SSL3 ?
|
3
Nick2VIPUser OP @rrfeng 嗯,这个参数验证过,加不加上目前都没有影响。至于 ssl3 我还不太懂...
|
4
Hardrain 2018-03-09 08:05:05 +08:00
根据配置与调试 SSL 的经验:
1. CA bundle file 是一个文件,包含 PEM(base64)编码的、被信任的所有根证书(CA Root)。Python 可能不使用操作系统的证书系统,就像 Mozilla 的 NSS。 2. ssl client cert file 是用于 SSL 双向认证的客户端证书,通常还有一个对应的私钥。一般的网站不使用双向认证,故在大多数情况下无需配置。 |
6
Nick2VIPUser OP @Hardrain 谢谢老哥!有些懂了。
python 访问 https 验证数字证书依赖的是 python 第三方库`certifi`(安装 requests 默认安装),`certifi`会在 Linux 非虚拟环境路径 ``` /usr/local/lib/python2.7/dist-packages/certifi/cacert.pem ``` 或者虚拟环境路径 ``` /root/.virtualenvs/virName/lib/python3.5/site-packages/certifi/cacert.pem ``` 创建一个.pem 文件 也就是说我去访问一个 https 网站 certifi 的 cacert.pem 文件会提供我需要验证的证书,所以能够正常访问。 同理如果我去访问一个第三方没有授权证书的 https 网站(例如 12306 自己做的证书),我就把 12306 的 CA Root 添加到 cacert.pem 后面应该就可以正常访问了。 |