有个需求,数据库有个表有将近 几千条 url 记录,每条记录都是一个图片,我须要请求他们拿到每一个图片存到本地。一开始我是这么写的(伪代码):sql
import requests 数据库
for url in urls: 服务器
try:socket
r = requests.get(url).content url
save_image(r) spa
except Exception, e: 日志
print str(e)code
然而在服务器上运行时, 会发现每隔一些请求会报相似下面的错误:图片
HTTPConnectionPool(host='wx.qlogo.cn', port=80):
Max retries exceeded with url: /mmopen/aTVWntpJLCAr2pichIUx8XMevb3SEbktTuLkxJLHWVTwGfkprKZ7rkEYDrKRr5icyDGIvU4iasoyRrqsffbe3UUQXT5EfMEbYKg/0 (
Caused by <class 'socket.error'>: [Errno 104] Connection reset by peer)
缘由,大概是由于我频繁请求,服务器关闭了部门请求链接get
import requests
for url in urls:
for i in range(10):
try:
r = requests.get(url).content
except Exception, e:
if i >= 9:
do_some_log()
else:
time.sleep(0.5)
else:
time.sleep(0.1)
break
save_image(r)
代码很简陋,但能够说明大致解决方案,在每一个请求间增长延时能够减小大部分请求拒绝,
但仍是存在一些请求被拒绝的,因此在那部分请求被拒绝后,发起重试,
在被拒 10 次后才善罢甘休(记录到日志)。
在实际的请求中,加了 0.1s 的延迟被拒绝的状况明显少了不少,
被拒绝重试的次数最多为 3 次,最后成功地取下了所有图片。