我有一个 Flask 应用程序,它使用 Selenium 运行 Python 脚本,并且它接收带有 Selenium 应该打开的 url 的 POST 请求。 Python 脚本托管在 Google Cloud 中的虚拟机上,当我使用 Flask 运行代码时,它工作得很好,并且发送到服务器的 POST 请求也得到了很好的解析。一切都按预期和预期进行。
我一直在尝试使用 Nginx、Gunicorn 和 systemd 来部署它,以获得 24/7 的正常运行时间,但是每当 POST 请求传递到我的服务器时,我都会在日志文件中收到以下错误:
selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: crashed.
(chrome not reachable)
(The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)
我已经查看了 StackOverflow 上关于此问题的所有其他线程,所有这些似乎都源于 chromedriver 配置问题或 Chrome 和 chromeDriver 的不兼容版本,但由于它在 Flask 本身上运行完全正常,但只有在我运行时才会中断通过 Nginx 和 Gunicorn 路由它,我非常怀疑情况是否如此。我检查了我的 chrome 和 chromeDriver 版本,它们似乎都很好(而且,一般来说,我相当确定我的所有路径也都在我的代码中的其他位置):
chromedriver --version
ChromeDriver 115.0.5790.170
google-chrome --version
Google Chrome 115.0.5790.170
selenium
Version: 4.11.2
因此,作为参考,这是我在 Python 文件中的配置:
from flask import Flask, request, jsonify
from flask_cors import CORS
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
import time
import logging
logging.basicConfig(filename='/home/username/logs.log', level=logging.INFO)
app = Flask(__name__)
CORS(app)
def open_url_in_selenium(url):
service = Service('/usr/local/bin/chromedriver')
service.start()
options = webdriver.ChromeOptions()
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('--disable-extensions')
options.add_argument('--remote-debugging-port=9222')
options.add_argument('--log-level=DEBUG')
options.add_argument('--enable-logging')
options.add_argument('--disable-software-rasterizer')
options.binary_location = '/usr/bin/google-chrome'
options.add_argument('--log-path=' + log_file_path)
driver = webdriver.Chrome(options=options)
driver.get(url)
return driver
这里是 systemd 服务单元(如果相关):
[Unit]
Description=XYZ thing
After=network.target
[Service]
User=username
Group=username
WorkingDirectory=/home/username
ExecStart=/usr/bin/gunicorn --workers 1 --bind X.X.X.X:XXXX server:app
Restart=always
[Install]
WantedBy=multi-user.target
还有最后一件事要注意:出于某种原因,即使我在 Flask 上运行代码,我也需要使用
sudo python3 filename.py
才能真正让代码在没有权限被拒绝的情况下运行。这可能是权限问题吗?当我运行 systemd 时,我也使用 sudo,所以我认为这会很好,但也许不是?以下是我一直在使用的命令:
sudo systemctl start service-unit-name
sudo systemctl enable service-unit-name
sudo systemctl stop service-unit-name
sudo systemctl restart service-unit-name
如果这是问题所在,有人可以解释如何正确配置权限吗?有人知道发生了什么事吗?我几个小时以来一直试图解决这个问题!非常感谢。
由于您使用的是最新的selenium(
v4.11.2
),因此您实际上不必传递chromedriver
和browser
的位置。 Selenium 可以为您下载和管理驱动程序。
尝试删除以下行,然后让 selenium 以编程方式下载
chromedriver
。
service = Service('/usr/local/bin/chromedriver')
service.start()
和
options.binary_location = '/usr/bin/google-chrome'
即使尝试了上述方法,如果仍无法启动浏览器,那么您可以尝试以下方法:
转到以下路径
usr/local/bin/chromedriver
,如果您看到任何旧驱动程序(除了v115
),请删除。
参考文献
您可以查看“环境”部分
Environment="PATH=/home/xxx/anaconda3/envs/proj/bin/**:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin**"