【问题标题】:Python script won't run from .bat file, Task Scheduler, or cmd promptPython 脚本不会从 .bat 文件、任务计划程序或 cmd 提示符运行
【发布时间】:2016-08-19 13:13:38
【问题描述】:

我有一个 Python 脚本,它在从 Eclipse、IDLE 运行时效果很好,双击目录文件夹中的 .py 文件。我需要让它每天晚上自动运行,但我无法从 Windows 任务计划程序运行它,所以我编写了一个 .bat 文件,它也不起作用。

Python 脚本:

import urllib.request
import time
from lxml import etree
import datetime
import csv
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders

today = datetime.date.today()
ts = int(time.time()) - 86400
tsend = int(time.time())
#ts = 1461253877
#tsend = 1461340277

dailyReport = "URL_GOES_HERE".format(ts, tsend)

with urllib.request.urlopen(dailyReport) as url:
    soup = url.read()
saveFile = open('{}_dailyIdleReport.xml'.format(today),'wb')
saveFile.write(soup)
saveFile.close()

tree = etree.parse('{}_dailyIdleReport.xml'.format(today))
root = tree.getroot()
print(root.tag, root.attrib)

zonarFile = open('{}_idleReport.csv'.format(today),'w', newline='')
outputWriter = csv.writer(zonarFile)
outputWriter.writerow(['Asset ID', 'Event Type', 'Idle Length', 'Cost'])

for assetidle in root.findall('assetidle'):
    for element in assetidle:
        for event in assetidle.findall('event'):
            fleet = assetidle.get('fleet')
            eventtype = event.get('type')
            length = event.find('length').text
            tlength = length
            (h, m, s) = tlength.split(':')
            result = ((float(h)/1) + (float(m)/60) + (float(s)/3600))
            cost = (result * 1.5) * 1.80
            displayCost = '${:,.2f}'.format(cost)            
            zonarFile = open('{}_idleReport.csv'.format(today),'a', newline='')
            outputWriter = csv.writer(zonarFile)
            outputWriter.writerow([fleet,eventtype,length,displayCost])
            zonarFile.close()            
            #print('Asset #:  %s  %s  %s  %s' %(fleet,eventtype,length,displayCost))

fromaddr = "myemail@server.com"
toaddr = "myemail@server.com"
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = toaddr
msg['Subject'] = "The Zonar %s" %'{}_idleReport.csv'.format(today)
body = "The Zonar Daily Idle Report is attached."

filename = "{}_idleReport.csv".format(today)
attachment = open("C:\\Users\\PeggyBall\\workspace\\ZonarCSCProject\\src\\{}_idleReport.csv".format(today), "rb")

part = MIMEBase('application', 'octet-stream')
part.set_payload((attachment).read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', "attachment; filename= %s" % filename)
body = "The Zonar Idle Report for {} is attached.".format(today)
msg.attach(MIMEText(body, 'plain'))
msg.attach(part)

server = smtplib.SMTP('smtp.email.serverhere', 587)
server.ehlo()
server.starttls()
server.ehlo()
server.login("email_username", "email_password")
text = msg.as_string()
server.sendmail(fromaddr, toaddr, text)

当前 .bat 文件:

@echo off
c:\Users\PeggyBall\AppData\Local\Programs\Python\Python35\python.exe c:\Users\PeggyBall\workspace\ZonarCSCProject\src\DailyIdleReport.py
pause

来自上述 .bat 文件的 CMD 输出(此输出是预期的,但 .xml 和 .csv 文件从未从 .bat 创建):

eventlist {'end': '1461716317', 'ver': '1', 'count': '38', 'start': '1461629917'}
Press any key to continue . . .

以前无效的 .bat 文件:

@echo off
C:\Users\PeggyBall\workspace\ZonarCSCProject\src\DailyIdleReport.py %*
pause

@echo off
C:\Users\PeggyBall\AppData\Local\Programs\Python\Python35\python.exe C:\Users\PeggyBall\workspace\ZonarCSCProject\src\DailyIdleReport.py %*
pause

这是错误信息:

eventlist {'ver': '1', 'end': '1461624597', 'count': '33', 'start': '1461538197'}
Traceback (most recent call last):
  File "C:\Users\PeggyBall\workspace\ZonarCSCProject\src\DailyIdleReport.py", line 68, in <module>
    attachment = open("C:\\Users\\PeggyBall\\workspace\\ZonarCSCProject\\src\\idleReport.csv","rb")
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\PeggyBall\\workspace\\ZonarCSCProject\\src\\idleReport.csv'
Press any key to continue . . .

我已将双 \ 删除为单个 \,但这也不起作用。任何建议将不胜感激。

谢谢!

【问题讨论】:

  • 脚本运行。它只是在attachment() 行出错。您确定不同文件夹中没有另一个 .py 文件吗?注意错误行没有在 csv 文件中格式化 today 带下划线。
  • 我清理了那个文件夹,还有其他名称不同的 .py 文件,但我已经删除了所有内容。我不能在附件的文件名中使用变量吗?我的计划是在文件名中包含报告的日期。
  • 是的,你可以。尝试再次运行指向正确 .py 的脚本。代码是否曾在目录中保存带有日期的 xml/csv 文件?
  • bat 文件中的行应该是什么?是的,当我从 Eclipse 或 .py 文件运行文件时,XML 和 csv 文件确实保存在该文件夹中,但在我运行 .bat 文件时没有。
  • 是否会发生完全相同的回溯?我看不出为什么您的 .bat 文件会产生与使用 Python IDE 不同的结果。我根本无法重现您的情况。我只能说仔细检查你的文件路径。

标签: python batch-file


【解决方案1】:

考虑在所有文件中指定一个绝对路径。目前,在您的外部文件的open() 中,假定了相对路径,如果批处理文件和命令行在外部运行,则会出现问题。

尝试将 .xml 和 .csv 文件保存到 .py 脚本的当前路径,任何对 .py 的调用(IDE 或命令行)都将使用这样的绝对路径。下面使用os.path.join() 连接目录和文件名。此函数与平台无关(Windows、Mac、Linux),避免了反斜杠或正斜杠需求,并且由于未设置硬编码路径,因此可以部署到其他用户。

import os
...

# CURRENT DIRECTORY OF RUNNING SCRIPT
cd = os.path.dirname(os.path.abspath(__file__))

# EXTERNAL FILE NAMES
xmlfile = os.path.join(cd, '{}_dailyIdleReport.xml'.format(today))
csvfile = os.path.join(cd, '{}_idleReport.csv'.format(today))

with urllib.request.urlopen(dailyReport) as url:
    soup = url.read()
saveFile = open(xmlfile, 'wb')
saveFile.write(soup)
saveFile.close()

tree = etree.parse(xmlfile)
root = tree.getroot()
print(root.tag, root.attrib)

zonarFile = open(csvfile,'w', newline='')
outputWriter = csv.writer(zonarFile)
outputWriter.writerow(['Asset ID', 'Event Type', 'Idle Length', 'Cost'])

for assetidle in root.findall('assetidle'):
    for element in assetidle:
        for event in assetidle.findall('event'):
            ...
            zonarFile = open(csvfile, 'a', newline='')

...
# ATTACHMENT
attachment = open(csvfile, "rb")

【讨论】:

  • 芭菲,你是救星!此解决方案有效,我非常感谢您对此提供的所有帮助!
  • 没问题。很高兴为您提供帮助!
猜你喜欢
  • 1970-01-01
  • 2020-09-25
  • 1970-01-01
  • 1970-01-01
  • 2020-08-07
  • 2020-07-13
  • 2020-02-05
  • 2018-05-17
  • 2014-02-28
相关资源
最近更新 更多