繁体   English   中英

通过PHP调用Python脚本时将挂起shell_exec()

[英]Python Script Hangs When Called via PHP shell_exec()

我有一个使用shell_exec从PHP调用的Python脚本,所有脚本工作正常,并且在Python脚本完成并且一切都按exepcted运行后,脚本又回到了PHP函数。

现在,我更改了Python脚本,使其包含一个上一级的类,该类创建了一个Web驱动程序,并将该驱动程序返回到通过对象调用该脚本的脚本,然后另一个函数关闭了作为参数传入的驱动程序。

由于设置了这个新类并添加了一个对象以使用chrome创建/关闭webdriver的驱动程序,因此Python脚本在完成后会挂起,并且永远不会将控制权交还给PHP脚本来完成处理。

我曾经看过php system()shell_exec()挂在浏览器上 ,也浏览http://php.net/manual/it/function.shell-exec.php#106250 ,但没有运气。

我需要运行PHP脚本,然后传递给Python脚本,等待Python脚本完成,然后移回PHP脚本以完成处理。

所有这些过程都是从Run.php的:

$reponse = shell_exec('python36 "script1.py" "https://www.example.com/" "23"');

目录结构

root_dir
    python_dir
        scripts_dir
            Script1.py
            Script2.py
            Script3.py
        Global.py
    run.php

全局

import re
from selenium import webdriver

class Global:

    def getDriver(self):
        try:
            chrome_options = webdriver.ChromeOptions()
            chrome_options.add_argument('headless')
            chrome_options.add_argument('no-sandbox')

            # Windows - Dev Environment
            driver = webdriver.Chrome(executable_path='C:\chromedriver.exe', chrome_options=chrome_options)
            # Linux - Prod Environment
            #driver = webdriver.Chrome(chrome_options=chrome_options)

            return driver
        except Exception as e:
            print('Error: ' + str(e.args[0]))

    def closeDriver(self, driver):
        try:
            driver.close()
            return None
        except Exception as e:
            print('Error: ' + str(e.args[0]))

scripts_dir中的所有脚本都有不同的代码,具体取决于执行的任务,但是新的Global对象对于所有脚本都是相同的,新的Global对象是对所有脚本的唯一更改,因为它们可以正常工作到目前为止,Python脚本已挂起。

Script1.py

import os, sys
ROOT_DIR = os.path.normpath(os.path.join(os.path.abspath(__file__), '../..'))
sys.path.insert(0, ROOT_DIR)
from Global import Global

globalObj = Global()

try:
    # Load all items on page
    driver = globalObj.getDriver()
    driver.get(PARAMS[1])

    #... code to create a JSON file and populate it.

    # Close webdriver
    globalObj.closeDriver(driver)

    print('Completed Ref: ' + str(PARAMS[2]))

except Exception as e:
    print('Error: ' + str(e.args[0]))

我没有在Python或PHP或任何其他日志中获得任何错误或警告,Python脚本运行并创建了应有的预期JSON文件,并且看起来一切正常,行print('Completed Ref: ' + str(PARAMS[2]))当Python脚本挂起时, print('Completed Ref: ' + str(PARAMS[2]))似乎没有打印出来。

在命令行上运行Script1.py大约需要35秒才能成功完成。

更新-2018年2月27日

如果我删除对getDrivercloseDriverGlobal类的调用,则脚本将运行并完成并返回PHP以继续处理。

Script1.py-更新

import os, sys
from selenium import webdriver

try:
    # Load all items on page
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument('headless')
    chrome_options.add_argument('no-sandbox')

    driver = webdriver.Chrome(executable_path='C:\chromedriver.exe', chrome_options=chrome_options)
    driver.get(PARAMS[1])

    #... code to create a JSON file and populate it.

    # Close webdriver
    driver.close()

    print('Completed Ref: ' + str(PARAMS[2]))

except Exception as e:
    print('Error: ' + str(e.args[0]))

该脚本在命令行中以及在使用上述示例的shell_exec通过PHP执行时均运行良好,因此在创建对象并调用getDrivercloseDriver类时肯定缺少closeDriver

更新2-27 Feb 2018

经过进一步测试后,我可以确认问题是由调用类Globalscript1.py脚本引起的, script1.py创建Webdriver并将其关闭,一旦我在script1.py删除了这些调用,脚本就可以正常运行。

我试图把在sys.exit()globalObj.closeDriver()我也试着del globalObj在没有运气剧本的结尾。

更新2018年2月3日至27日

我已将网络驱动程序从Chrome更改为Firefox和PhantomJS,其他驱动程序在Global类上也可以正常工作,看起来它可能与现阶段的Chrome驱动程序有关。

我正在使用Chrome 64.0.3282.186 (Official Build) (64-bit)和Chromedriver 2.35

您可以在获取参数后尝试使用WebDriverWait,该参数要等到过程结束

myElem = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.NAME, 'name_of_element')))

*我正在使用firefox驱动程序。

看起来是driver.close()是问题的原因。 您需要在.quit()中使用.quit()来结束chromedriver进程,否则该进程将不会终止,这就是Python脚本看起来好像挂着的原因。

从:

driver.close()

至:

driver.quit()

暂无
暂无

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

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