为啥我在无限循环中休眠的 python 脚本停止运行?

Posted

技术标签:

【中文标题】为啥我在无限循环中休眠的 python 脚本停止运行?【英文标题】:Why does my python script with sleep in infinite loop stop running?为什么我在无限循环中休眠的 python 脚本停止运行? 【发布时间】:2020-12-21 13:33:07 【问题描述】:

我正在使用 python 脚本将数据从 .xlsx 文件传输到 html:我使用 pandas 读取/解析 excel 并使用 beautifulsoup 编辑 html(从两个 .txt 文件中读取这两个文件的路径)。这本身就有效。但是,此脚本必须持续运行,因此所有内容都在无限 while 中调用,每 15 分钟循环一次,每次消息都显示在控制台上。

我的问题如下:由于某种原因,在任意数量的循环之后,代码不再运行,我的意思是控制台上没有文本,html 文件中没有任何更改。发生这种情况时,我必须重新运行它才能让它再次运行。

这里是主要功能:

def mainFunction():
    if getattr(sys, 'frozen', False):
        application_path = os.path.dirname(sys.executable)
    elif __file__:
        application_path = os.path.dirname(__file__)

    excelFiles = open(str(application_path) +"\\pathsToExcels.txt")
    htmlFiles = open(str(application_path) +"\\pathsToHTMLs.txt")
    sheetFiles = open(str(application_path) +"\\sheetNames.txt")

    print("Reading file paths ...")
    linesEx = excelFiles.readlines()
    linesHtml = htmlFiles.readlines()
    linesSheet = sheetFiles.readlines()

    print("Begining transfer")
    for i in range (len(linesEx)):
        excel = linesEx[i].strip()
        html = linesHtml[i].strip()
        sheet = linesSheet[i].strip()

        print("Transfering data for " + sheet)
        updater = UpdateHtml(excel, sheet, str(application_path) + "\\pageTemplate.html", html)
        updater.refreshTable()
        updater.addData()
        updater.saveHtml()

    print("Transfer done")
    excelFiles.close()
    htmlFiles.close()
    sheetFiles.close()

UpdateHtml 是真正负责数据传输的人。

"__main__" 也包含 while 循环:

if __name__ == "__main__":
    while(True):
        print("Update at " + str(datetime.now()))
        mainFunction()
        print("Next update in 15 minutes\n")
        time.sleep(900)

最后,启动这个的批处理代码

python "C:\Users\Me\PythonScripts\excelToHtmlTransfer.py"

pause

根据我通过试验注意到的情况,当sleep 设置为小于 5 分钟(仍然会发生 5 分钟)或完全省略时,不会发生这种情况。

有人知道为什么会发生这种情况吗?或者在这种情况下sleep 的任何替代品?

编辑:UpdateHtml:

import pandas as pd
from bs4 import BeautifulSoup

class UpdateHtml:
    def __init__(self, pathToExcel, sheetName, pathToHtml, pathToFinalHtml):
        with open(pathToHtml, "r") as htmlFile:
            self.soup = BeautifulSoup(htmlFile.read(), features="html.parser")
        self.df = pd.read_excel (pathToExcel, sheet_name=sheetName)
        self.html = pathToFinalHtml
        self.sheet = sheetName
    
    def refreshTable(self):
       #deletes the inner html of all table cells
        for i in range(0, 9):
            td = self.soup.find(id = 'ok' + str(i))
            td.string = ''
            td = self.soup.find(id = 'acc' + str(i))
            td.string = ''
            td = self.soup.find(id = 'nok' + str(i))
            td.string = ''
            td = self.soup.find(id = 'problem' + str(i))
            td.string = '' 

    def prepareData(self):
        #changes the names of columns according to their data
        counter = 0
        column_names = 
        for column in self.df.columns: 
            if 'OK' == str(self.df[column].values[6]):
                column_names[self.df.columns[counter]]  = 'ok'
            elif 'Acumulate' == str(self.df[column].values[6]):
                column_names[self.df.columns[counter]]  = 'acc'
            elif 'NOK' == str(self.df[column].values[6]):
                column_names[self.df.columns[counter]]  = 'nok'
            elif 'Problem Description' == str(self.df[column].values[7]):
                column_names[self.df.columns[counter]]  = 'prob'
            counter += 1
            
        self.df.rename(columns = column_names, inplace=True)

    def saveHtml(self):
        with open(self.html, "w") as htmlFile:
            htmlFile.write(self.soup.prettify())
    
    def addData(self):
        groupCounter = 0
        index = 0

        self.prepareData()

        for i in range(8, 40):
            #Check if we have a valid value in the ok column
            if pd.notna(self.df['ok'].values[i]) and str(self.df['ok'].values[i]) != "0":
                td = self.soup.find(id = 'ok' + str(index))
                td.string = str(self.df['ok'].values[i])
            #Check if we have a valid value in the accumulate column
            if pd.notna(self.df['acc'].values[i]) and str(self.df['acc'].values[i]) != "0":
                td = self.soup.find(id = 'acc' + str(index))
                td.string = str(self.df['acc'].values[i])
            #Check if we have a valid value in the nok column
            if pd.notna(self.df['nok'].values[i]) and str(self.df['nok'].values[i]) != "0":
                td = self.soup.find(id = 'nok' + str(index))
                td.string = str(self.df['nok'].values[i])
            #Check if we have a valid value in the problem column
            if pd.notna(self.df['prob'].values[i]):
                td = self.soup.find(id = 'problem' + str(index))
                td.string = str(self.df['prob'].values[i])
            if groupCounter == 3:
                index += 1
                groupCounter = 0
            else:
                groupCounter += 1

我正在使用的 excel 有点奇怪,因此我为什么要执行这么多(看似)冗余操作。不过,它必须保持目前的形式。 主要的是包含数据的“行”实际上是由 4 个常规行组成的,因此需要groupCounter

【问题讨论】:

有一个很好的机会,UpdateHtml 负责,但您没有提供定义或导入提示。 我建议使用crontab 安排此脚本的运行,而不是脚本本身内的无限循环。此方法将在 Python 解释器意外退出的情况下提供额外的保护,只有那些迭代受到影响,而不一定是随后的迭代。 @JPI93 它应该在 Windows Server 2012 上运行,我认为它不支持 Cron 代码是否停止运行(即进程是否死机)或代码是否停止执行任何可观察的操作(即进程是否挂起)? @pancakeSort 我明白了,抱歉,我对基于 Windows 的服务器/系统知之甚少 - 尽管他们没有提供与 crontab 类似功能的任务计划程序吗? 【参考方案1】:

找到了解决此问题的方法。基本上我所做的是在批处理脚本中移动循环,如下所示:

:whileLoop
python "C:\Users\Me\PythonScripts\excelToHtmlTransfer.py"
timeout /t 900 /nobreak
goto :whileLoop

让它运行几个小时后,这种情况不再发生,但不幸的是我仍然不知道是什么原因造成的。

【讨论】:

以上是关于为啥我在无限循环中休眠的 python 脚本停止运行?的主要内容,如果未能解决你的问题,请参考以下文章

PHP 在循环中无限休眠

在脚本中并行运行 2 个无限循环,并在脚本停止时终止

当 python 脚本休眠时服务停止

运行无限循环并从“外部”获取命令(例如 shell 或其他脚本)

错误 R10(引导超时)Heroku 与 python 脚本

Python - 用于停止无限循环的键盘命令? [重复]