解决Python请求中MaxRetryError问题

报错信息:
raise MaxRetryError(_pool, url, error or ResponseError(cause))\nurllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='172.17.0.1', port=443): Max retries exceeded with url: /api/events/rule/?page_size=20&lock_id=140351160399616 (Caused by SSLError(SSLEOFError(8, 'EOF occurred in violation of protocol (_ssl.c:877)'),))
原因分析:
    参数 verify=False,同时,requests默认是keep-alive的,可能没有释放,
解决方案:
    加参数
        sess = requests.Session()
        sess.mount('http://', HTTPAdapter(max_retries=3))
        sess.mount('https://', HTTPAdapter(max_retries=3))
        sess.keep_alive = False # 关闭多余连接

        text = requests.get(self.target_img_url, headers=headers, stream=True, verify=False, timeout=(5,5)) #  connect 和 read 二者的 timeout,所以是一个数组

        with open(img_files_path, 'wb') as file:
            for i in text.iter_content(1024 * 10):
                file.write(i)

        text.close() # 关闭,很重要,确保不要过多的链接
通过Python的requests库访问一个HTTPS服务,但是遇到了一个`MaxRetryError`错误,这通常是由于请求的连接超出了最大重试次数。从错误信息来看,问题似乎与SSL协议的EOF(文件结束)发生违规有关,这可能是由于某些原因导致SSL连接意外关闭。

对于你给出的解决方案,我进行了一些分析:

1. 你设置了`verify=False`,这意味着你关闭了对SSL证书的验证。这可能会导致安全问题,因为这意味着你可能会接受一个假冒的证书。通常,我们不推荐在生产环境中关闭SSL证书验证。
2. 你创建了一个requests会话并设置了最大重试次数。这是一个好做法,因为它确保了如果一个请求失败,它会被重新发送,而不是直接失败。
3. 你设置了`sess.keep_alive=False`,这是为了确保在完成请求后关闭连接。这是一个好做法,因为它可以帮助释放系统资源。
4. 你使用了`text.close()`来关闭响应对象。这是一个好做法,因为它确保了所有资源都被正确释放。

然而,这里存在一些问题:

1. 当你使用`verify=False`时,你可能会遇到安全问题。你应该考虑使用一个CA证书包来验证SSL证书,例如`verify=True`或`verify='/path/to/certfile'`。
2. 在使用requests的get方法时,你已经使用了参数`stream=True`。这意味着数据是逐步下载的,而不是一次性下载。但是,你在使用`iter_content`方法时设置了10KB的块大小。如果你的响应体非常大,那么这种方法可能会非常慢。你可以考虑增加块大小或完全禁用流式传输。

下面是一个改进的代码示例:
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_context

# 创建会话并设置最大重试次数
sess = requests.Session()
sess.mount('http://', HTTPAdapter(max_retries=3))
sess.mount('https://', HTTPAdapter(max_retries=3))

# 使用自定义的SSL上下文来验证SSL证书
context = create_urllib3_context(ssl_version=None)
sess.verify = '/path/to/certfile'  # 指向你的CA证书包路径

# 发送GET请求
response = sess.get('https://172.17.0.1/api/events/rule/?page_size=20&lock_id=140351160399616', timeout=(5, 5), verify=context)

# 检查响应状态码以确保请求成功
if response.status_code == 200:
    with open('output_file', 'wb') as file:
        for chunk in response.iter_content(chunk_size=8192):  # 使用更大的块大小以提高速度
            file.write(chunk)
else:
    print(f"Request failed with status code {response.status_code}")
这个示例解决了你的问题,并且还修复了一些潜在的问题。希望这对你有所帮助!

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值