Python 通过 PHP shell_exec() 调用时脚本挂起
Python Script Hangs When Called via PHP shell_exec()
我有一个 Python 脚本,使用 shell_exec
从 PHP 调用,一切正常,脚本在 Python 脚本已完成,一切正常。
现在我已经更改了 Python 脚本以包含一个 class 从它创建一个网络 driver 和 returns driver到通过 object 调用它的脚本,然后另一个函数关闭作为参数传入的 driver。
自从设置这个新的 class 并使用 chrome 添加 object 到 create/close 一个 driver for webdriver Python 脚本在完成后挂起,它永远不会将控制权交还给 PHP 脚本以完成处理。
我看过 php system() shell_exec() hangs the browser and also at 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
Global.py
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
object 内容对于所有脚本都是相同的, new Global object 是对所有脚本所做的唯一更改,因为它们到目前为止工作正常,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 文件他们应该并且看起来都正常工作,当 Python 脚本挂起时,行 print('Completed Ref: ' + str(PARAMS[2]))
似乎没有打印出来。
运行 Script1.py
在命令行上大约需要 35 秒才能成功完成。
更新 - 2018 年 2 月 27 日
如果我删除对 Global
class 到 getDriver
和 closeDriver
的调用,那么脚本 运行 将完成并返回给 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]))
脚本 运行 在命令行和通过 PHP 使用 shell_exec
执行时都很好,使用上面的例子,所以当它出现时一定有我遗漏的东西创建一个 object 并调用 getDriver
或 closeDriver
classes.
2018 年 2 月 2 日 - 27 日更新
经过进一步测试,我可以确认问题是由 script1.py
脚本调用 class Global
创建网络 driver 并关闭它引起的,一旦我在 script1.py
中删除这些调用,脚本 运行 就可以了。
我试过在 globalObj.closeDriver()
之后加入 sys.exit()
,我也试过在脚本末尾加入 del globalObj
,但没有成功。
2018 年 2 月 3 - 27 日更新
我已经将 webdriver 从 Chrome 更改为 Firefox 和 PhantomJS,其他 drivers 在全局 class 上运行良好,看起来像可能与现阶段的Chromedriver有关。
我正在使用 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()
与 Chromedriver 一起使用以结束 chromedriver 进程,否则该进程将不会终止,这就是 Python 脚本看起来像是挂起的原因。
发件人:
driver.close()
收件人:
driver.quit()
我有一个 Python 脚本,使用 shell_exec
从 PHP 调用,一切正常,脚本在 Python 脚本已完成,一切正常。
现在我已经更改了 Python 脚本以包含一个 class 从它创建一个网络 driver 和 returns driver到通过 object 调用它的脚本,然后另一个函数关闭作为参数传入的 driver。
自从设置这个新的 class 并使用 chrome 添加 object 到 create/close 一个 driver for webdriver Python 脚本在完成后挂起,它永远不会将控制权交还给 PHP 脚本以完成处理。
我看过 php system() shell_exec() hangs the browser and also at 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
Global.py
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
object 内容对于所有脚本都是相同的, new Global object 是对所有脚本所做的唯一更改,因为它们到目前为止工作正常,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 文件他们应该并且看起来都正常工作,当 Python 脚本挂起时,行 print('Completed Ref: ' + str(PARAMS[2]))
似乎没有打印出来。
运行 Script1.py
在命令行上大约需要 35 秒才能成功完成。
更新 - 2018 年 2 月 27 日
如果我删除对 Global
class 到 getDriver
和 closeDriver
的调用,那么脚本 运行 将完成并返回给 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]))
脚本 运行 在命令行和通过 PHP 使用 shell_exec
执行时都很好,使用上面的例子,所以当它出现时一定有我遗漏的东西创建一个 object 并调用 getDriver
或 closeDriver
classes.
2018 年 2 月 2 日 - 27 日更新
经过进一步测试,我可以确认问题是由 script1.py
脚本调用 class Global
创建网络 driver 并关闭它引起的,一旦我在 script1.py
中删除这些调用,脚本 运行 就可以了。
我试过在 globalObj.closeDriver()
之后加入 sys.exit()
,我也试过在脚本末尾加入 del globalObj
,但没有成功。
2018 年 2 月 3 - 27 日更新
我已经将 webdriver 从 Chrome 更改为 Firefox 和 PhantomJS,其他 drivers 在全局 class 上运行良好,看起来像可能与现阶段的Chromedriver有关。
我正在使用 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()
与 Chromedriver 一起使用以结束 chromedriver 进程,否则该进程将不会终止,这就是 Python 脚本看起来像是挂起的原因。
发件人:
driver.close()
收件人:
driver.quit()