简体   繁体   English

批处理文件未在任务计划程序中运行python脚本

[英]Batch file not running python script in task scheduler

I have a scrapping python script and a batch file that when run from CMD works perfectly however when I try to run it from Task Scheduler nothing happens. 我有一个剪贴的python脚本和一个批处理文件,当从CMD运行时,它可以完美运行,但是当我尝试从Task Scheduler运行时,什么也没发生。

I know there are a lot of questions regarding the same issue but I have tried all of the proposed answers and non of them seem to work. 我知道关于同一问题有很多问题,但是我已经尝试了所有建议的答案,但似乎都没有。

Don't know if this is relevant but script would open Firefox and scrape some websites. 不知道这是否相关,但是脚本会打开Firefox并刮擦某些网站。

Have tried adding full permissions to the folders and files that I am using. 尝试将完全权限添加到我正在使用的文件夹和文件中。 Also, have tried in Task Scheduler to set up "Run wheter user is logged on or not", "Run with highest privileges" , "Start in (optional): add/bactch/file/path" and so on 另外,已经尝试在Task Scheduler中设置“运行或不运行用户”,“以最高权限运行”,“开始于(可选):添加/脚本/文件/路径”等

Batch file: 批处理文件:

py "C:\python_test\myscript.py"

It should run the python script which opens Firefox and scrapes some websites, gets their links and saves them in a csv file 它应该运行python脚本,该脚本会打开Firefox并刮取一些网站,获取其链接并将其保存在csv文件中

Here is myscript.py: 这是myscript.py:

import datetime
import time
import csv
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
import os

file_path = r"C:\General\{0:%Y%m%d}\results{0:%Y%m%d%H%M%S}.csv".format(datetime.datetime.now())
directory = os.path.dirname(file_path)

try:
    os.stat(directory)
except:
    os.mkdir(directory)

from bs4 import BeautifulSoup


def init_driver():
    caps = DesiredCapabilities.FIREFOX
    caps['marionette'] = True
    driver = webdriver.Firefox(capabilities=caps)
    driver.wait = WebDriverWait(driver, 15)
    return driver


xpath = {
    'english': '//*[@id="xxx"]',
    'soort': '//*[@id="xxx"]/option[text()=\'|- Announcement of change in denominator or in thresholds\']',
    'start': '//*[@id="xxx"]',
    'end': '//*[@id="xxx"]',
    'submit': '//*[@id="xxx"]',
    'pub_sort': '//*[@id="xxx"]',
}

if __name__ == "__main__":

    driver = init_driver()
    try:
        driver.get("http://SOMEWEBSITE") 
        driver.find_element_by_css_selector('[id$=hplEnglish]').click()
    except Exception:
        DoNothing = ""


    time.sleep(2)
    driver.find_element_by_css_selector('[id$=hplEnglish]').click()
    time.sleep(3)
    #alert_obj = driver.switch_to.alert
    #alert_obj.dismiss()
    #driver.find_element_by_xpath(xpath['english']).click()
    today = datetime.datetime.now()
    driver.wait.until(EC.element_to_be_clickable((By.XPATH, xpath['soort']))).click()
    driver.find_element_by_xpath(xpath['start']).send_keys((today-datetime.timedelta(weeks=1)).strftime('%d/%m/%Y'))
    driver.find_element_by_xpath(xpath['end']).send_keys(today.strftime('%d/%m/%Y'))
    driver.find_element_by_xpath(xpath['submit']).click()
    for i in range(2):
        driver.wait.until(EC.element_to_be_clickable((By.XPATH, xpath['pub_sort']))).click()
    time.sleep(5)
    html = driver.page_source
    driver.quit()

    results = BeautifulSoup(html, 'html.parser').find('div', { 'id': 'SearchResults'}).table
    res = [['issuer', 'type', 'date']]
    for x in results.find_all('tr')[1:]:
        # print(x.text.strip())
        try:
            a, b, c = [i.text.strip() for i in x.find_all('td', class_='resultItemTop')[:3]]
            res.append([a,b,c])
        except ValueError:
            continue


    with open(file_path, 'w', newline='') as result:
        writer = csv.writer(result, delimiter=',')
        writer.writerows(res)
        print('finished')

Introduction 介绍

I suggest to read first What must be taken into account on executing a batch file as scheduled task? 我建议先阅读, 在执行作为计划任务的批处理文件时必须考虑什么?

Issue 1: Current directory 问题1:当前目录

The first issue here is most likely the current directory on running the batch file. 这里的第一个问题很可能是运行批处理文件时的当前目录。

Windows sets the directory of the batch file as current directory on double clicking a batch file, except the batch file path is a UNC path starting with \\\\computername\\share\\ . Windows双击一个批处理文件将批处理文件的目录设置为当前目录,但批处理文件路径是以\\\\computername\\share\\开头的UNC路径。

The current directory for a scheduled task is by default %SystemRoot%\\System32 , ie the Windows system directory which of course is special protected against modifications. 默认情况下,计划任务的当前目录为%SystemRoot%\\System32 ,即Windows系统目录,当然,该目录特别受保护,不能进行修改。 Many batch files expect that the current directory is the directory of the batch file and not any other directory. 许多批处理文件期望当前目录是该批处理文件的目录,而不是其他任何目录。

Solution 1: Define Start in directory in properties of scheduled task. 解决方案1:在计划任务的属性中的目录中定义“ 启动”

  • Start Windows Task Scheduler . 启动Windows Task Scheduler
  • Navigate to the task and double click on it to open the Properties of the task. 导航到任务,然后双击它以打开任务的属性
  • Select tab Action and click on button Edit . 选择选项卡操作 ,然后单击按钮编辑
  • There is Start in (optional) . Start in(可选) Enter here the path of the executed batch file. 在此处输入执行的批处理文件的路径。
  • Click two times on button OK to save this important modification in properties. 在“ 确定 ”按钮上单击两次,以将该重要修改保存在属性中。

Solution 2: Make batch file directory the current directory using CD . 解决方案2:使用CD将批处理文件目录设置为当前目录。

In the batch file insert after first line being usually @echo off the line: 在批处理文件中,通常在第一行之后插入@echo off

cd /D "%~dp0"

This command line changes the current directory from default %SystemRoot%\\System32 to the directory of the batch file as long as the batch file is not started using a UNC path. 只要未使用UNC路径启动批处理文件,此命令行就会将当前目录从默认的%SystemRoot%\\System32更改为批处理文件的目录。

Open a command prompt window and run cd /? 打开命令提示符窗口并运行cd /? for help on command CD and option /D . 有关命令CD和选项/D

Solution 3: Make batch file directory the current directory using PUSHD . 解决方案3:使用PUSHD将批处理文件目录设置为当前目录。

This solution is best if the batch file is stored on a network resource accessed using UNC path and of course the scheduled task is configured to run with credentials (user account and password) with permissions to read content of the batch file on the network resource. 如果批处理文件存储在使用UNC路径访问的网络资源上,并且计划任务配置为使用凭据(用户帐户和密码)运行且具有读取网络资源上批处理文件内容的权限,则此解决方案是最佳的。

In the batch file insert after first line being usually @echo off the lines: 在批处理文件中,通常在第一行之后@echo off插入以下行:

setlocal EnableExtensions DisableDelayedExpansion
pushd "%~dp0"

The batch file should additionally contain as last two line executed before exiting batch file processing the two lines: 批处理文件还应至少包含最后两行,然后退出处理两行的批处理文件:

popd
endlocal

Open a command prompt window and run pushd /? 打开命令提示符窗口并运行pushd /? , popd /? popd /? , setlocal /? setlocal /? and endlocal /? endlocal /? for help on these four commands and read also this answer for even more details on these four commands. 寻求有关这四个命令的帮助,并阅读此答案以获取有关这四个命令的更多详细信息。

Solution 4: Code everything to be independent on current directory. 解决方案4:将所有内容编码为独立于当前目录。

The fourth solution is writing batch file and Python script for being independent on which directory is the current directory on execution of batch file and Python script. 第四个解决方案是编写批处理文件和Python脚本,以独立于执行批处理文件和Python脚本时的当前目录是哪个目录。

This solution requires that all files and directories are specified with full qualified file/folder name which means full path + file/folder name + file extension. 此解决方案要求所有文件和目录均指定完整的合格文件/文件夹名称,这意味着完整路径+文件/文件夹名称+文件扩展名。

The full file/folder paths can be derived from known paths on execution like path of the batch file which can be referenced with %~dp0 inside the batch file and which expands to a path string always ending with backslash which means it can be concatenated with file/folder names without usage of an additional backslash. 完整的文件/文件夹路径可以从执行时的已知路径中获取,例如批处理文件的路径,可以在批处理文件内用%~dp0进行引用,并且可以扩展为始终以反斜杠结尾的路径字符串,这意味着可以将其与文件/文件夹名称,不使用其他反斜杠。

See also Wikipedia article about Windows Environment Variables . 另请参阅有关Windows环境变量的 Wikipedia文章。

Issue 2: Environment variables 问题2:环境变量

Scheduled tasks are often executed with built-in local system account. 计划任务通常使用内置的本地系统帐户执行。 So all environment variables defined just for the user account used on developing and testing the batch file either are not defined at all or are defined different. 因此,仅为在开发和测试批处理文件中使用的用户帐户定义的所有环境变量要么根本没有定义,要么定义不同。

Open from Windows Control Panel from item System the Advanced system settings or press key combination Win+Break if keyboard has a key Break (often as alternate function requiring pressing additionally the key Fn ) and clicking next on Advanced system settings on left side. 打开从Windows 控制面板从产品系统高级系统设置或按键组合运+歇如果键盘有一个键 (经常交替功能需要按下另外的关键,FN)和点击在左侧高级系统设置下。 The System Properties dialog is opened wit tab Advanced selected containing at bottom the button Environment Variables... which must be clicked to open the Environment Variables window. 将打开“ 系统属性”对话框,然后选择“ 高级”选项卡,该选项卡的底部包含“ 环境变量... ”按钮,必须单击该按钮才能打开“ 环境变量”窗口。

There are two lists of environment variables: User variables for ... and System variables . 环境变量有两个列表:...的用户变量系统变量 The system variables are defined for all accounts including built-in local system account. 系统变量是为所有帐户定义的,包括内置的本地系统帐户。 The user variables are defined only for the displayed user. 用户变量仅为显示的用户定义。

The user variables defined for current user are important and could be a reason why a batch file executed with a double click by current user works, but does not work on being executed as scheduled task with built-in system account. 为当前用户定义的用户变量很重要,这可能是为什么当前用户双击执行的批处理文件可以工作,但不能作为具有内置系统帐户的计划任务执行的原因。 A user PATH is often a main source of not working batch file on execution as scheduled task if the used scripts and executables depend on specific folder paths in local PATH defined in user PATH . 如果使用的脚本和可执行文件依赖于用户 PATH定义的本地 PATH特定文件夹路径,则用户 PATH通常是无法按计划执行任务的批处理文件的主要来源。

Please take a look on What is the reason for "X is not recognized as an internal or external command, operable program or batch file"? 请查看“无法将X识别为内部或外部命令,可操作程序或批处理文件”的原因是什么? for more information about system , user and local PATH and environment variable PATHEXT used on writing in a batch file just py instead of the script/executable file with full qualified file name. 有关system用户本地 PATH以及环境变量PATHEXT更多信息,用于在批处理文件中仅写入py而不是具有完全限定文件名的脚本/可执行文件。

So it is definitely better to use 所以绝对好用

"C:\Python27\python.exe" "C:\python_test\myscript.py"

instead of using 而不是使用

py "C:\python_test\myscript.py"

which results in cmd.exe searching around for a file py using local PATHEXT and local PATH environment variables which can file if the folder containing file py is defined in user PATH . 这导致cmd.exe使用本地 PATHEXT本地 PATH环境变量在文件py搜索,如果在用户 PATH定义了包含py的文件夹,则该文件可以归档。

I have not installed Python and so don't know what py really is. 我尚未安装Python ,所以不知道py到底是什么。 It could be a batch file with file name py.cmd or py.bat in which case the command CALL must be used if the batch file contains additional command lines after the command line with py and which perhaps depends on user environment variables. 它可能是文件名为py.cmdpy.bat的批处理文件,在这种情况下,如果批处理文件在py命令行之后包含其他命令行,并且可能取决于用户环境变量,则必须使用命令CALL It could be a symbolic link to python.exe in installation folder of Python . 它可能是指向Python安装文件夹中python.exe的符号链接。 I don't know. 我不知道。

Issue 3: Network resources 问题3:网络资源

Many scheduled tasks access files, folders or data via a network. 许多计划任务通过网络访问文件,文件夹或数据。 In this case the scheduled task must be configured to run with the credentials (user account and password) which has the required permissions to access the files, folders or data on the network resource. 在这种情况下,必须将计划任务配置为使用凭据(用户帐户和密码)运行,该凭据具有访问网络资源上的文件,文件夹或数据所需的权限。 The usage of the built-in local system account is in this case nearly never the right choice to run the scheduled task because of local system account has usually no permissions to read/write data on any network resource. 在这种情况下,内置本地系统帐户的使用几乎永远不是运行计划任务的正确选择,因为本地系统帐户通常无权在任何网络资源上读取/写入数据。

Conclusion 结论

It is good practice in my opinion to write a batch file being executed as scheduled task to be as independent as possible on other batch files and environment variables not defined in the batch file executed by Windows task scheduler itself. 在我看来,优良作法是编写一个作为计划任务执行的批处理文件,以尽可能独立于Windows任务计划程序本身执行的其他批处理文件和未在该批处理文件中定义的环境变量。 A design with dependencies on other script files and variables defined outside main script cause often sooner or later (sometimes years later) unexpected execution problems. 依赖于其他脚本文件和在主脚本之外定义的变量的设计通常会迟早(有时是几年后)导致意外的执行问题。

The programmer of a script written for execution as scheduled task should really know very well on which files, libraries, environment variables and registry keys/values the script and called executables depend on to work properly. 编写为按计划任务执行的脚本的程序员应该非常了解脚本和被调用的可执行文件正常运行所依赖的文件,库,环境变量和注册表项/值。

A batch file containing only one line to execute one application with some parameters is completely unnecessary and just a potential source of not working scheduled task because of the executable to run and its parameters can be in this case also directly set in properties of the scheduled task. 仅包含一行以一个参数执行一个应用程序的批处理文件是完全不必要的,并且由于要运行的可执行文件,潜在的原因是无法运行计划任务,在这种情况下,也可以直接在计划任务的属性中设置其参数。 There is absolutely no need to run %SystemRoot%\\System32\\cmd.exe with implicit option /C to process a specified batch file containing only one command line to execute an application with zero or more parameters because of Windows task scheduler can directly run the application with its parameters, too. 由于Windows任务计划程序可以直接运行Windows Server Scheduler,因此绝对不需要运行带有隐式选项/C %SystemRoot%\\System32\\cmd.exe来处理仅包含一个命令行的指定批处理文件,以执行具有零个或多个参数的应用程序。应用程序及其参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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