利用Python多執行緒限制 http 真實請求時間或限制函式最大執行時間的裝飾器
阿新 • • 發佈:2018-11-06
這段時間在製作一個爬蟲的時候發現了一個比較神奇的事情 python requests 包發起請求的時候設定 timeout 引數 竟然不起作用?
what 你要弄啥么蛾子嘞, 後來各種找原因終於在別人的提醒下又看了下 requests 的文件才發現原來 timeout 設定超時只是指發起到對方伺服器接受到請求這段時間,原文:timeout
僅對連線過程有效,與響應體的下載無關。 timeout
並不是整個下載響應的時間限制,而是如果伺服器在 timeout
秒內沒有應答,將會引發一個異常(更精確地說,是在timeout
秒內沒有從基礎套接字上接收到任何位元組的資料時)If no timeout is specified explicitly, requests do not time out.
沒辦法,因為業務需要必須要嚴格控制響應時間只好利用 python 的多執行緒來製作了一個非同步的限制函式執行時間的裝飾器:
import requests,datetime,time import threading class MyThread(threading.Thread): def __init__(self,target,args=()): """ why: 因為threading類沒有返回值,因此在此處重新定義MyThread類,使執行緒擁有返回值 此方法來源 https://www.cnblogs.com/hujq1029/p/7219163.html?utm_source=itdadao&utm_medium=referral """ super(MyThread,self).__init__() self.func = target self.args = args def run(self): #接受返回值 self.result = self.func(*self.args) def get_result(self): #執行緒不結束,返回值為None try: return self.result except Exception: return None #為了限制真實請求時間或函式執行時間的裝飾器 def limit_decor(limit_time): """ :param limit_time: 設定最大允許執行時長,單位:秒 :return: 未超時返回被裝飾函式返回值,超時則返回 None """ def functions(func): #執行操作 def run(*params): thre_func = MyThread(target=func,args=params) #主執行緒結束(超出時長),則執行緒方法結束 thre_func.setDaemon(True) thre_func.start() #計算分段沉睡次數 sleep_num = int(limit_time // 1) sleep_nums = round(limit_time % 1, 1) #多次短暫沉睡並嘗試獲取返回值 for i in range(sleep_num): time.sleep(1) infor = thre_func.get_result() if infor: return infor time.sleep(sleep_nums) #最終返回值(不論執行緒是否已結束) return thre_func.get_result() return run return functions
總之把這個裝飾器對公司的部分程式碼進行了下優化, 效果是非常非常不錯的。再也沒有出現因單個爬蟲請求超時而導致整個程式碼執行時間而延長的情況出現。
本文原創,如需轉載請註明來源。
注 : 網路爬蟲要儘量減小對被爬取網站影響, 如在被爬取網站每天訪問量較小的時間段去爬取,一切為了和平發展。