Python+request超時和重試
一、什么是超時?
1、連接超時
連接超時指的是沒連接上,超過指定的時間內都沒有連接上,這就是連接超時。(連接時間就是httpclient發送請求的地方開始到連接上目標主機url地址的時間)
2、讀取超時
讀取超時表示的是連接上了,但是讀數據時超過了指定的時間范圍,這就是讀取超時(讀取時間就是HttpClient已經連接到了目標服務器,然后進行內容數據的獲取的時間)
二、為什么要設置重試?
比如連接超時,程序就一直處於無響應狀態。這時我們需要去不斷重試連接,但也不可能是無止境的去重試,所以需要設置一個timeout超時時間。在timeout超時時間內如果無法連接到目標主機url地址,就返回一個異常錯誤(將這個連接超時的的特殊url寫到log日志中,方便管理員查看;讀取的數據量大,或者是目標服務器本身的問題(比如讀取數據庫慢,並發量大等...)也會影響讀取時間也可以設置讀取超時就返回報錯。方便業務管理和問題定位)
1-1 連接超時案例(原始)
import requests url = 'http://www.google.com.hk' r = requests.get(url) print(r.text)
運行結果:
raise ConnectionError(e, request=request) requests.exceptions.ConnectionError: HTTPConnectionPool(host='www.google.com.hk', port=80): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x0404D230>: Failed to establish
a new connection: [WinError 10060] 由於連接方在一段時間后沒有正確答復或連接的主機沒有反應,連接嘗試失敗。',))
由1-1案例可以看到因為連接超時,報了一個ConnectionError連接異常。所以為了防止程序因為連接超時報異常導致程序停止運行。我們就使用try……except……做一個異常處理。
1-2 連接超時案例(加requests異常處理)
import requests import time url = 'http://www.google.com.hk'
try: print(time.strftime('%Y-%m-%d %H:%M:%S')) r = requests.get(url) except requests.exceptions.ConnectionError as e: print("連接超時") print(time.strftime('%Y-%m-%d %H:%M:%S'))
運行結果:
2019-09-24 16:54:50 連接超時 2019-09-24 16:55:11
由1-2案例可以看出,使用try……except……異常處理后,沒有再報錯。並且可以看出默認的超時時間是21秒
1-3連接超時案例(修改默認超時時間)
import requests import time url = 'http://www.google.com.hk'
try: print(time.strftime('%Y-%m-%d %H:%M:%S')) r = requests.get(url,timeout=5)#timeout修改了超時時間,以秒為單位
except requests.exceptions.ConnectionError as e: print("連接超時") print(time.strftime('%Y-%m-%d %H:%M:%S'))
運行結果:
2019-09-24 17:16:52 連接超時 2019-09-24 17:16:57
由案例1-3得出,設置timeout=5后,默認超時時間被修改成了5秒。所以當碰到一些頁面請求時間相應時間過長的情況下,我們可以適當的延長超時時間來達到成功訪問頁面
1-4連接超時案例(設置多次請求次數)
import requests import time from requests.adapters import HTTPAdapter url = 'http://www.google.com.hk' s = requests.Session() s.mount('http://',HTTPAdapter(max_retries=3))#設置重試次數為3次
s.mount('https://',HTTPAdapter(max_retries=3)) try: s.get(url,timeout=5) except requests.exceptions.ConnectionError as e: print('連接失敗,該URL可能被牆掉了')
運行結果:
連接失敗,該URL可能被牆掉了
參考文檔:https://www.jianshu.com/p/0a15c253a0d9(設置requests中的重復請求) 、https://2.python-requests.org//zh_CN/latest/user/advanced.html#transport-adapters(requests 2.18.1中文文檔中適配器和請求超時)