最近在爬公告,但是用 Pdfminer3k 把PDF轉成TXT的時候由於某些PDF格式不規範很容易出現轉一個文件要很久出現類似於程序假死的狀況,然而事實上這種情況出現的時候我更偏向於跳過這個公告等全部爬完後統一處理,所以我就給PDF轉TXT的函數加了一個裝飾器來專門應對這種情況。主要的功能是對每一個循環設置最大運行時間,如果一次循環運行時間超過這個閾值,就跳過這次循環進入下一個循環,類似於 requests 庫的 timeout 功能。只不過 requests 庫的 timeout 是內嵌的,只在調用 requests 時才能使用,而這個裝飾器的 timeout 功能可以用於腳本中的任一個函數。
這個裝飾器函數來自腳本之家,這裏只是稍作修改。發到自己的博客上只是爲了記錄和存儲,方便日後查看。
import signal
import time
def set_timeout(num, callback):
def wrap(func):
def handle(signum, frame): # 收到信號 SIGALRM 後的回調函數,第一個參數是信號的數字,第二個參數是the interrupted stack frame.
raise RuntimeError
def to_do(*args, **kwargs):
try:
signal.signal(signal.SIGALRM, handle) # 設置信號和回調函數
signal.alarm(num) # 設置 num 秒的鬧鐘
r = func(*args, **kwargs)
signal.alarm(0) # 關閉鬧鐘
return r
except RuntimeError as e:
callback()
return to_do
return wrap
def after_timeout(): # 超時後的處理函數
print("do something after timeout.")
使用的時候語法如下:
@set_timeout(50,after_timeout())
def parse(evendate, docucode):
print("這是需要加載timeout功能的函數")
參考鏈接: