有個需求,數據庫有個表有將近 幾千條 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 次,最後成功地取下了所有圖片。