VK群组帖子图片保存遇requests.exceptions.ConnectTimeout问题求助
VK群组图片保存时的ConnectTimeout问题解决
我在保存VK群组帖子里的图片时,遇到了requests.exceptions.ConnectTimeout错误,具体报错信息如下:
requests.exceptions.ConnectTimeout: HTTPSConnectionPool(host='sun1-95.userapi.com', port=443): Max retries exceeded with url: /impg/DKsod3pGDta5b1qODuCmR1u_wiTvWWO33PzrjA/m43mpFGA5qA.jpg?size=510x629&quality=95&sign=364cbe4ad52971f2f26e3f89919aba83&c_uniq_tag=L1vm9aX43cGpZQk5gSG60gH2874jU-KM4sTaPyEiEwQ&type=album (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001F647F59E90>, 'Connection to sun1-95.userapi.com timed out. (connect timeout=None)'))
我尝试用循环重试的代码修复,但运行几分钟后还是出现大量报错:
connect_loop = True while connect_loop: try: res = requests.get(url, timeout=3) connect_loop = False except requests.exceptions.RequestException: # любая ошибка requests print('ConnectionError') continue
优化方案
1. 加重试间隔,别死磕请求
你那代码没设重试间隔,短时间内反复刷请求,服务器很容易把你当成恶意爬虫直接拒接。试试在每次重试前加个随机延迟,避免被限制:
import time import random connect_loop = True retry_count = 0 max_retries = 10 # 别无限循环,设个最大重试次数 while connect_loop and retry_count < max_retries: try: # 分开设连接超时和读取超时,比单设3秒合理 res = requests.get(url, timeout=(3, 10)) if res.status_code == 200: connect_loop = False # 这里写保存图片的逻辑 with open('saved_img.jpg', 'wb') as f: f.write(res.content) else: print(f"请求炸了,状态码: {res.status_code}") retry_count += 1 time.sleep(random.uniform(1, 3)) # 随机等1-3秒再试 except requests.exceptions.RequestException as e: print(f"连接出错: {str(e)}") retry_count += 1 time.sleep(random.uniform(2, 5)) # 出错了就多等会儿,2-5秒
2. 别只设一个超时值
原代码timeout=3是总超时,建议分开设连接超时和读取超时,比如timeout=(3,10)——3秒内连不上就算超时,10秒内拿不到响应也算超时,这样更贴合实际场景。
3. 一定要限死最大重试次数
无限循环重试纯纯浪费资源,搞不好还会被服务器拉黑IP。设个最大重试次数,超过了就把这个图片记下来,后面再处理,别死磕。
4. 检查下网络环境
VK的图片服务器在有些地区访问本来就不稳定,试试换个网络,或者看看是不是本地防火墙、DNS污染搞的鬼。
5. 用requests自带的重试机制(更省心)
不用自己写循环,用HTTPAdapter加Retry就能实现自动重试,还能自定义重试策略:
import requests from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry session = requests.Session() # 配置重试策略 retry_strategy = Retry( total=5, # 最多重试5次 backoff_factor=1, # 重试间隔按1、2、4秒指数增长 status_forcelist=[429, 500, 502, 503, 504], # 遇到这些状态码就重试 allowed_methods=["GET"] # 只给GET请求开重试 ) adapter = HTTPAdapter(max_retries=retry_strategy) session.mount("https://", adapter) session.mount("http://", adapter) try: response = session.get(url, timeout=(3, 10)) response.raise_for_status() # 有HTTP错误直接抛出来 with open('saved_img.jpg', 'wb') as f: f.write(response.content) except requests.exceptions.RequestException as e: print(f"最终还是失败了: {str(e)}")
内容的提问来源于stack exchange,提问作者Vadim
相关产品推荐
相关产品推荐

