[爬虫问题]请求 https 站点时, requests 中 verify 参数<CA bundle file>和<ssl client cert file>分别指的什么文件?如何获取呢?

2018-03-08 18:25:03 +08:00
 Nick2VIPUser

使用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 上右上角具有绿色安全标识

查找资料后

  1. 如果网站是<有效证书>,那么 verify=False 或者 True 都可以访问。
  2. 可以自己传入参数设置CA_BUNDLE文件或者具有CA 证书的目录。
  3. 可以指定一个本地证书作为客户端证书(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.

不理解的问题

  1. CA_BUNDLE文件或CA 证书是否就是第三方机构颁发的具有数字签名的证书?在什么情况下需要自己指定,如何获取此文件呢?
  2. ssl client cert file客户端证书文件的作用是什么?如何获取?爬虫过程中需要自己指定吗?
  3. 问题中提到的访问 SSLError 异常可能是什么导致的?

对问题 3 的猜测

接下来的动作

如果您能看到这里,真的非常感谢
如果各位老哥有了解或遇到过类似的问题可以帮忙一起讨论,灰常谢谢!

7311 次点击
所在节点    Python
6 条回复
rrfeng
2018-03-08 18:36:16 +08:00
爬虫建议直接不验证证书
客户端证书不需要。
rrfeng
2018-03-08 18:36:56 +08:00
不是 SSL 版本问题吗?还 SSL3 ?
Nick2VIPUser
2018-03-08 21:04:21 +08:00
@rrfeng 嗯,这个参数验证过,加不加上目前都没有影响。至于 ssl3 我还不太懂...
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 双向认证的客户端证书,通常还有一个对应的私钥。一般的网站不使用双向认证,故在大多数情况下无需配置。
Hardrain
2018-03-09 08:06:09 +08:00
@rrfeng 这个 ssl3 很可能是 OpenSSL 的代码 /API 中的命名空间。
不表示正在使用 SSLv3
Nick2VIPUser
2018-03-09 09:54:57 +08:00
@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 后面应该就可以正常访问了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/436240

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX