简体   繁体   中英

Python script won't run from .bat file, Task Scheduler, or cmd prompt

I have a Python script which works great when running from Eclipse, IDLE, double clicking on the .py file in the directory folder. I need to automate this to run every night but I cannot get it to run from the Windows Task Scheduler so I've written a .bat file and it does not work either.

Python script:

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)

Current .bat file:

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

CMD output from above .bat file (this output is expected but the .xml and .csv files are never created from .bat):

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

Previous .bat files that didn't work:

@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

Here is the error message:

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 . . .

I've removed the double \\ to a single \\ but that didn't work either. Any suggestions would be greatly appreciated.

Thanks!

Consider designating an absolute path in all files. Currently, in open() of your external files, relative paths are assumed which will be problematic if batch files and command lines are run externally.

Try saving .xml and .csv files to current path of .py script and any call to .py (IDEs or command line) will use such an absolute path. Below uses the os.path.join() to concatenate directory and file names. This function is platform agnostic (Windows, Mac, Linux) and avoids the back or forward slash needs and works in deployment to other users as no hard-coded paths are set.

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")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM