首页 5G技术

Python 爬虫:攻克 HTTPS 网站 SSL 证书校验难题

分类:5G技术
字数: (2658)
阅读: (7262)
内容摘要:Python 爬虫:攻克 HTTPS 网站 SSL 证书校验难题,

在进行网络爬虫开发时,经常会遇到需要抓取第三方 HTTPS 网站数据的情况。但由于各种复杂的网络环境和服务器配置,我们可能会遇到 SSL 相关的异常,导致爬虫无法正常工作。本文将深入分析这些 SSL 异常的成因,并提供详细的解决方案,帮助开发者解决 Python 爬虫在访问第三方 HTTPS 网站时遇到的 SSL 异常处理问题。

常见的 SSL 异常场景

  • ssl.SSLCertVerificationError 这是最常见的 SSL 证书验证错误,通常是由于服务器使用了自签名证书、证书过期或证书链不完整导致的。
  • requests.exceptions.SSLError requests 库抛出的 SSL 错误,可能是由于 OpenSSL 版本过低、TLS 协议不匹配等原因引起的。
  • urllib3.exceptions.MaxRetryError 当使用 urllib3 库时,如果遇到 SSL 错误并且重试次数超过限制,就会抛出此异常。
  • 服务器配置问题: 例如服务器禁用了某些 TLS 版本,导致客户端无法建立连接。

SSL 异常的底层原理分析

SSL/TLS 协议的工作原理涉及复杂的密钥交换和加密过程。简单来说,客户端在与服务器建立连接时,服务器会提供自己的 SSL 证书。客户端需要验证该证书的有效性,包括:

  1. 证书是否由受信任的 CA 机构颁发: 客户端会检查证书的颁发者是否在自己的信任列表中。
  2. 证书是否过期: 客户端会检查证书的有效期。
  3. 证书的域名是否与访问的域名匹配: 客户端会检查证书中的域名是否与自己访问的域名一致,防止中间人攻击。

如果以上任何一个环节出现问题,客户端就会拒绝建立连接,并抛出 SSL 相关的异常。而对于一些老旧的 HTTPS 网站,可能使用了较老的 TLS 协议,而 Python 爬虫默认使用的协议版本可能较高,导致无法握手。

解决方案一:禁用 SSL 证书验证(不推荐)

最简单粗暴的方法是禁用 SSL 证书验证。在 requests 库中,可以通过设置 verify=False 来实现:

Python 爬虫:攻克 HTTPS 网站 SSL 证书校验难题
import requests

response = requests.get('https://example.com', verify=False) # 禁用 SSL 证书验证
print(response.status_code)

警告: 这种方法虽然简单,但是存在很大的安全风险,容易受到中间人攻击,强烈不建议在生产环境中使用。仅建议在测试或抓取不重要的网站时使用。

解决方案二:指定 CA 证书

如果你知道目标网站的证书由哪个 CA 机构颁发,可以将该 CA 证书添加到 requests 的信任列表中:

import requests

response = requests.get('https://example.com', verify='/path/to/ca.pem') # 指定 CA 证书
print(response.status_code)

/path/to/ca.pem 是 CA 证书文件的路径。你可以从 CA 机构的网站下载该文件。

Python 爬虫:攻克 HTTPS 网站 SSL 证书校验难题

解决方案三:使用 certifi 库

certifi 库提供了一份更新的 CA 证书列表,可以解决部分证书验证问题。安装 certifi 库:

pip install certifi

然后在代码中使用:

import requests
import certifi

response = requests.get('https://example.com', verify=certifi.where()) # 使用 certifi 提供的 CA 证书
print(response.status_code)

解决方案四:指定 TLS 协议版本

对于某些老旧的网站,可能需要指定 TLS 协议版本才能正常连接。可以使用 ssl 模块来实现:

Python 爬虫:攻克 HTTPS 网站 SSL 证书校验难题
import requests
import ssl

class TLSAdapter(requests.adapters.HTTPAdapter):
    def init_poolmanager(self, *args, **kwargs):
        ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
        ctx.options |= ssl.OP_NO_TLSv1  # 禁用 TLSv1.0
        ctx.options |= ssl.OP_NO_TLSv1_1  # 禁用 TLSv1.1
        ctx.minimum_version = ssl.TLSVersion.TLSv1_2 # 设置最低 TLS 版本为 1.2

        kwargs['ssl_context'] = ctx
        return super(TLSAdapter, self).init_poolmanager(*args, **kwargs)

session = requests.Session()
session.mount('https://', TLSAdapter())

response = session.get('https://example.com') # 使用指定 TLS 协议版本的 session
print(response.status_code)

这段代码创建了一个自定义的 TLSAdapter,用于指定 TLS 协议版本。 可以根据实际情况调整 ssl.OP_NO_TLSv1ssl.OP_NO_TLSv1_1ctx.minimum_version 的值。

解决方案五:使用 Nginx 反向代理

如果目标网站的 SSL 配置存在问题,可以考虑使用 Nginx 作为反向代理。Nginx 可以处理 SSL 握手,并将请求转发到目标服务器。

在 Nginx 的配置文件中,可以配置 SSL 证书、TLS 协议版本等参数。

Python 爬虫:攻克 HTTPS 网站 SSL 证书校验难题
server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /path/to/certificate.pem; # SSL 证书路径
    ssl_certificate_key /path/to/key.pem;     # SSL 证书密钥路径

    ssl_protocols TLSv1.2 TLSv1.3;  # 允许的 TLS 协议版本

    location / {
        proxy_pass https://target.com; # 目标服务器地址
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

注意:配置 Nginx 反向代理时,需要确保服务器的防火墙允许 443 端口的流量通过。如果使用宝塔面板,可以在面板中进行端口放行操作。同时,Nginx 的并发连接数也需要根据实际情况进行调整,避免服务器负载过高。

实战避坑经验总结

  1. 优先尝试更新 certifi 库: 这是最简单且有效的解决方案,可以解决大部分证书验证问题。
  2. 避免禁用 SSL 证书验证: 除非在非常特殊的情况下,否则不要禁用 SSL 证书验证,以确保安全性。
  3. 检查目标网站的 SSL 配置: 使用在线 SSL 检测工具(例如:myssl.com)检查目标网站的 SSL 配置,找出问题所在。
  4. 逐步排查: 从简单的解决方案开始,逐步尝试更复杂的方案,例如指定 TLS 协议版本或使用 Nginx 反向代理。
  5. 注意服务器的防火墙设置: 确保服务器的防火墙允许 HTTPS 流量通过。
  6. 关注 Python 官方文档和 requests 库的更新: 及时了解最新的安全漏洞和修复方案。

通过以上方法,相信你能够有效地解决 Python 爬虫在访问第三方 HTTPS 网站时遇到的 SSL 异常问题,提升爬虫的稳定性和安全性。

Python 爬虫:攻克 HTTPS 网站 SSL 证书校验难题

转载请注明出处: 代码一只喵

本文的链接地址: http://m.acea3.store/blog/183769.SHTML

本文最后 发布于2026-04-04 13:49:53,已经过了23天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 摸鱼达人 5 天前
    有没有更详细的 Nginx 配置教程啊?比如如何配置 SNI,以及如何开启 HSTS 保护。
  • 接盘侠 1 天前
    Nginx 反向代理这个思路不错,相当于把 SSL 握手这部分交给更专业的工具来处理了。不过配置 Nginx 还是需要一些经验的。
  • 咸鱼翻身 5 天前
    certifi 这个库确实很方便,可以省去手动管理 CA 证书的麻烦。不过还是要定期更新,保持证书列表的最新状态。