certificate_verify_failed 错误源于本地 python 环境信任链问题,非爬虫代码错误;主因是 ca 证书过期或缺失,推荐优先升级 certifi 并显式指定 verify=certifi.where();verify=false 仅限调试且禁用于生产,自签名证书需手动导入 pem 文件,时间不同步也会导致验证失败。

CERTIFICATE_VERIFY_FAILED 错误不是爬虫写错了,而是你的 Python 环境无法信任目标网站的 SSL 证书。根本原因通常不在网站端,而在你本地——证书信任链断裂、根证书过期、或系统/Python 安装没带完整 CA 证书包。
certifi.where() 是什么?为什么它常是第一解法
certifi.where() 返回 requests 官方维护的最新 CA 证书文件路径,比操作系统自带证书库更新更及时、跨平台一致性更好。很多 macOS 或 Docker 镜像里的 Python 默认不带完整证书包,直接导致验证失败。
- 执行
pip install --upgrade certifi升级证书库 - 在 requests 请求中显式指定:
requests.get(url, verify=certifi.where()) - 如果仍报错,说明问题不在证书包本身(比如目标站用自签名证书),这时才考虑其他方案
verify=False 的真实效果与风险边界
verify=False 让 requests 跳过全部 SSL 验证:证书链追溯、域名匹配、有效期检查、吊销状态查询全都不做。连接能通,但中间人攻击(如公司代理、公共 Wi-Fi)可任意篡改响应内容。
- ✅ 仅限本地调试,且应配合
urllib3.disable_warnings()抑制警告(否则会反复提示) - ❌ 生产环境绝对禁用;
Session对象每次新建都要重新设verify=False,不会继承 - ⚠️ 它不解决任何根本问题,只是绕过验证——就像拔掉烟雾报警器来避免误报
自签名或内网证书该怎么处理
企业测试环境、本地 HTTPS 服务常用自签名证书,这类证书不被公共 CA 信任,但你可以主动导入:- 把内网 CA 的根证书(
internal-ca.pem)放到项目目录或系统可信位置 - 请求时指定路径:
requests.get("@#@#@#@#@#@#@#@#@#@0", verify="/path/to/internal-ca.pem") - 若证书链不完整,需确保 PEM 文件里包含服务器证书 + 所有中间证书 + 根证书(顺序不限,但都得有)
容易被忽略的时间同步问题
SSL 验证严格依赖系统时间。哪怕证书本身有效,只要本机时间偏差超过几十秒,就会被判定为“已过期”。- 运行
ntpdate -s time.windows.com(Linux/macOS)或检查 Windows 时间服务 - 不要跳过这步直接改代码——尤其在容器或云主机上,时间漂移很常见
-
openssl s_client -connect example.com:443 -showcerts可查证书实际有效期,辅助判断是否真过期
证书验证失败的根源往往藏在环境里,而不是代码里。修对地方,比加十个 verify=False 更省事也更安全。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











