PHP(Laravel)调用含Selenium-Firefox的Python脚本问题咨询
嘿,看你在Laravel里用PHP调用Python的Selenium脚本操作Firefox,我来给你捋捋可能遇到的问题和解决办法,毕竟这种跨语言调用的坑还真不少。
先确认下你的当前环境和现有代码:
你的配置与代码
当前环境
- 最新版Firefox浏览器
- Selenium 3.11.0
- Geckodriver 0.20.0
- Laravel框架(PHP)
现有代码片段
PHP(Laravel)执行脚本代码
$scrape = 'python '.base_path().'Description\test.py 2>&1'; $output = shell_exec($scrape); echo($output);
Python脚本(test.py)开头部分
from selenium import webdriver from selenium.webdriver.firefox.options import Options from selenium.webdriver.firefox.firefox_binary import FirefoxBinary # 后续业务逻辑...
接下来是几个关键的排查和优化点:
路径别踩坑!
你用base_path().'Description\test.py'的时候要注意,PHP里字符串的\是转义字符,Windows下应该写成\\,或者更稳妥的是直接用/——不管Windows还是Linux,PHP和Python都认这个路径分隔符,比如改成base_path().'/Description/test.py'。另外,先把生成的$scrape命令打印出来,手动在终端跑一遍,看看路径对不对,能不能正常执行,这是最快排查路径问题的方法。权限和环境变量必须到位
服务器上跑的时候,Web服务(Apache/Nginx)的运行用户得有这几个权限:执行Python脚本、访问Firefox程序、读取Geckodriver。另外,Geckodriver最好加到系统PATH里,或者直接在Python脚本里写绝对路径指定它的位置:driver = webdriver.Firefox(executable_path='/绝对路径/geckodriver')如果Firefox不是装在默认位置,也要用
FirefoxBinary指定路径:binary = FirefoxBinary('/绝对路径/firefox.exe') driver = webdriver.Firefox(firefox_binary=binary, executable_path='/绝对路径/geckodriver')无头模式一定要开(服务器环境)
服务器一般没图形界面,不开无头模式Firefox根本启动不了,在Python脚本里加上这段配置:options = Options() options.add_argument('--headless') options.add_argument('--disable-gpu') # Windows环境可能需要这个参数来规避渲染问题 driver = webdriver.Firefox(options=options, executable_path='/绝对路径/geckodriver')调试要抓准错误信息
你加了2>&1把错误输出重定向过来,这点做得很好!执行后一定要看$output里的内容,不管是模块找不到、路径错了还是权限不够,错误信息都会直接告诉你问题在哪。另外,也可以试试用exec()替代shell_exec(),它能返回脚本的退出状态码,0代表成功,非0就是出错了,调试起来更方便:$command = 'python '.base_path().'/Description/test.py 2>&1'; exec($command, $output, $return_var); echo "退出状态码: $return_var\n"; print_r($output);
先从这些点排查,应该能解决大部分问题。
内容的提问来源于stack exchange,提问作者Zeion

