Python requests 使用心得

最近在用requests寫一些項目,碰見了一些問題,百度了不少,有些都不太好使,最後看了下requestsAPI文檔,才明白了不少,最後項目趨於穩定。看來學東西仍是API文檔比較權威啊~python

問題場景

項目須要經過一臺主機搭上代理向目標服務器定時交換數據,主機上同時跑着比較佔用資源的其餘項目。git

項目設計思路

由於主機上已經運行了比較佔用線程內存資源的其餘項目,因此計劃本項目就應該在不能太佔用資源,的前提下保持比較流暢的運行。json

設計了在線程下加上定時器的思路,定時運行相關網絡請求方法。服務器

請求量 :每隔5秒鐘,發送10 ~ 30個請求。網絡

核心代碼

headers = {"Content-Type": "application/json;charset=uf8"}
url = config.baseurl + path
try:
    
    response = requests.post(url, data= data, headers=headers ,stream= False,timeout= 10)

except Exception as indentfier:

    time.sleep(5)
    getLoaclObjs(False)

par = json.loads(data)

if response != None:
    print(" method name = ", par["IPCType"],"\n sendData = ",json.dumps(par), "\n response.state.code = ",response.status_code,"\n response.text = ",response.text,"\n\n", url, "\n\n")

問題:

報錯:

HTTPConnectionPool(host='172.19.5.101', port=8085): Max retries exceeded with url: <url >(Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x006DB1F0>, 'Connection to <server ip> timed out. (connect timeout=10)'))

分析:

報錯的重點在於 connect timeoutsession

解決方案

1.因爲是timeout的報錯,因此爲了項目穩定首先要作的就是作好重連操做,在代碼中其實已經作好了 try ... except 中 except中爲錯誤處理。再次調用了方法。app

2.處理事後數據交互沒有了毛病,可是報錯仍然頻繁,甚至後邊有了新的錯誤:post

requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionAbortedError(10053, '你的主機中的軟件停止了一個已創建的鏈接。', None, 10053, None))

度娘和overflow都告訴我添加一下代碼:

#設置重連次數
requests.adapters.DEFAULT_RETRIES = 15
# 設置鏈接活躍狀態爲False
s = requests.session()
s.keep_alive = False

基本上意思就是發出的網絡請求比較頻繁,requests內置的urllibs3不能及時的爲咱們斷開鏈接,因而就有了以上報錯。
代碼的基本意思就是斷開鏈接、增長重試次數。網站

headers = {"Content-Type": "application/json;charset=uf8"}
url = config.baseurl + path
try:
     #設置重連次數
    requests.adapters.DEFAULT_RETRIES = 15
    # 設置鏈接活躍狀態爲False
    s = requests.session()
    s.keep_alive = False
    response = requests.post(url, data= data, headers=headers ,stream= False,timeout= 10)

except Exception as indentfier:

    time.sleep(5)
    getLoaclObjs(False)

par = json.loads(data)

if response != None:
    print(" method name = ", par["IPCType"],"\n sendData = ",json.dumps(par), "\n response.state.code = ",response.status_code,"\n response.text = ",response.text,"\n\n", url, "\n\n")

還有別的處理方法就是增長代理,因爲主機是用代理的,因此項目換別的代理就不太現實,不然有可能直接鏈接不上目標服務器。url

因而想到了直接管理內存,文檔上是這麼表述的:

好消息——歸功於 urllib3,同一會話內的持久鏈接是徹底自動處理的!同一會話內你發出的任何請求都會自動複用恰當的鏈接!
注意:只有全部的響應體數據被讀取完畢鏈接纔會被釋放爲鏈接池;因此確保將 stream 設置爲 False 或讀取 Response 對象的 content 屬性。

也就是說除非stream=False或者response.content /response.text被操做,否則該請求不會被釋放。
同其餘的自動管理內存的語言同樣,不論垃圾回收仍是引用計數,都存在一個問題就是內存釋放比較緩慢,因而我就在代碼中手動關閉了鏈接。

headers = {'Content-Type': "application/json;charset=uf8"}
    url = baseurl + path
    response = None
    try:
        #設置重連次數
        requests.adapters.DEFAULT_RETRIES = 5
        s = requests.session()
        # 設置鏈接活躍狀態爲False
        s.keep_alive = False
        response = requests.post(url, data=data, headers=headers,stream=False,timeout= 10)
        # 關閉請求  釋放內存
        response.close()
        del(response)  
    except Exception as indentfier:

        time.sleep(5)
        timer = threading.Timer(timerFlag, upload_position)
        timer.start()

最終有效減小了報錯次數。

__End ~

   
   
   

友情連接:

我的網站       技術博客        簡書主頁

相關文章
相關標籤/搜索