我是使用 selenium 的 python flask 新手,我在 Heroku 上托管了 Flask API,该 API 会抓取我所在大学的网站以检索出勤数据并返回。该 API 已使用 Gunicorn WSGI 托管,并且运行正常。但是当同时有多个 API 调用时,它会给出一个错误,提示页面因选项卡崩溃而崩溃。
ERROR in app: Exception on /attend [POST] Traceback (most recent call last): File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app response = self.full_dispatch_request() File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 1518, in full_dispatch_request rv = self.handle_user_exception(e) File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 1516, in full_dispatch_request rv = self.dispatch_request() File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 1502, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args) File "/app/app/main.py", line 29, in attend driver.get("https://academia.srmist.edu.in/#View:My_Attendance") File "/app/.heroku/python/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py", line 436, in get self.execute(Command.GET, {'url': url}) File "/app/.heroku/python/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py", line 424, in execute self.error_handler.check_response(response) File "/app/.heroku/python/lib/python3.9/site-packages/selenium/webdriver/remote/errorhandler.py", line 247, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.WebDriverException: Message: unknown error: session deleted because of page crash from tab crashed (Session info: headless chrome=97.0.4692.99)
第一个 API 调用崩溃,但第二个 API 调用成功并返回数据。
该函数的起始代码是:
app = Flask(__name__) app.config['JSON_SORT_KEYS'] = False import os os.environ['DISPLAY'] = ':0' @app.route('/attend',methods=["POST"]) def attend(): options = webdriver.ChromeOptions() options.add_argument('--disable-dev-shm-usage') driver = webdriver.Chrome(ChromeDriverManager().install()) input_json = request.get_json(force=True) id = input_json["id"] password = input_json["pass"] driver.get("https://academia.srmist.edu.in/#View:My_Attendance") ...
我尝试添加 chrome 选项,如“–disable-dev-shm-usage”和“–no-flags”,但这似乎对标签崩溃没有任何影响。我希望 API 能够进行多次调用,并向所有调用发送数据,即使它们同时被调用。我还想使用 selenium 网格,但我不确定它是否会起作用。
我用于 Heroku 应用程序的构建包是:
https://github.com/heroku/heroku-buildpack-chromedriver https://github.com/heroku/heroku-buildpack-google-chrome
我遇到了同样的错误(您的问题是我在网上能找到的唯一另一个例子),这几天让我抓狂不已。我通过为每个.get调用创建一个新的、独立的驱动程序实例并在使用后在下次调用之前关闭它来解决这个问题。
.get
对于它是否能满足您的需求,我不太清楚,但是 Heroku 已停止抛出所有异常。
如果可能的话,您是否尝试在驱动程序选项中添加 page_load_strategy = ‘eager’?我意识到等待所有内容加载会导致 Heroku 偶尔抛出超时错误(这可能是导致我的情况出现页面崩溃错误的原因,很久以前就修复了,记不清了),而只等待 DOM 加载会使我的程序执行速度提高多个数量级