解决:requests.exceptions.proxyerror: httpsconnectionpool(host=‘www.xxxx.com’, port=443): max retries exceeded with url
背景
报错问题
requests.exceptions.proxyerror: httpsconnectionpool(host='www.xxxx.com', port=443): max retries exceeded with url: / (caused by proxyerror('cannot connect to proxy.', timeout('_ssl.c:1108: the handshake operation timed out')))
报错翻译
主要报错信息内容翻译如下所示:
requests.exceptions.proxyerror: httpsconnectionpool(host='www.xxxx.com', port=443): max retries exceeded with url: / (caused by proxyerror('cannot connect to proxy.', timeout('_ssl.c:1108: the handshake operation timed out')))
翻译:
requests.exceptions.proxy错误:httpsconnectionpool(host='ww.xxxx.com',port=443):url超过了最大重试次数:/(由proxyerror('cannot connect to proxy.',timeout('_ssl.c:1108:握手操作超时')引起)
报错位置代码
报错原因
经过查阅资料,发现这个错误产生的原因是 ssl
证书报错,http连接太多没有关闭导致http的连接数超过最大限制。由于http默认情况下连接是keep-alive的,所以这就导致了服务器保持了太多连接而不能再新建连接,不然就会产生这样的错误提示。
具体扣一分以下三种情况:
-
ip被封
-
程序请求速度过快。
-
使用了代理
小伙伴们按下面的解决方法即可解决!!!
解决方法
要解决这个错误有以下几种方法。
方法一:增加睡眠时间,减少访问频率
代码是:
time.sleep()
方法二:关闭 ssl 验证,设置verify=false
response = requests.get(fpath_or_url,headers=headers,stream=true, verify=false)
使用这种方案解决的时候,出现以下警告:
insecurerequestwarning: unverified https requestisbeing made. adding certificate verificationisstrongly advised.
在语句前加上以下代码即可不会被报错:
requests.packages.urllib3.disable_warnings()
方法三:释放请求链接
requests默认是keep-alive的,可能没有释放,加参数 headers={‘connection’:‘close’}
# todo ssl证书报错,参数 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() # 关闭,很重要,确保不要过多的链接
方法四:改变重连次数,设置 requests.adapters.default_retries = 5
try:
headers = {
'user-agent': 'mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/79.0.3945.88 safari/537.36',
}
# todo 增加连接重试次数(一共4次链接)
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() # 关闭,很重要,确保不要过多的链接
except exception as e:
print(e,self.target_img_url)
方法五:sni支持
由于python2不支持sni,具体sni了解转:http://blog.csdn.net/makenothing/article/details/53292335 如果想python2支持sni,pip安装3个模块:
1.pyopenssl
2.ndg-httpsclient
3.pyasn1
然后在使用requests请求前添加如下代码:
import urllib3.contrib.pyopenssl
urllib3.contrib.pyopenssl.inject_into_urllib3()
方法六:设置不使用或关闭代理
os.environ[‘no_proxy’]设置为你的目标网址的域名即可。
如果要设置多个域名:
但是一定要是字符串型,不然会报错,源码:
其中,这个os.environ,意思就是系统变量,[‘no_proxy’]的意思就是指定某个域名别用代理去处理。
如果没有设置代理,可以看一下windows窗口,有没有:
fiddler,关闭fiddler之后就可以正常处理了。
方法七:降低requests和urllib3版本
最新的urllib3有更严格ssl的校验,所以,用以下方案解决
pip uninstall requests urllib3 # 先卸载
pip install requests==2.27 urllib3==1.25.8 -i https://pypi.doubanio.com/simple # 指定版本安装,不然默认会装最新版
参考内容
python 爬虫:https; httpsconnectionpool(host=‘z.jd.com’, port=443)
发表评论