小能豆

调用多个 API 时,页面因选项卡崩溃而崩溃 - Heroku 上的带有 Flask 的 Selenium

py

我是使用 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

阅读 17

收藏
2025-01-03

共1个答案

小能豆

我遇到了同样的错误(您的问题是我在网上能找到的唯一另一个例子),这几天让我抓狂不已。我通过为每个.get调用创建一个新的、独立的驱动程序实例并在使用后在下次调用之前关闭它来解决这个问题。

对于它是否能满足您的需求,我不太清楚,但是 Heroku 已停止抛出所有异常。

如果可能的话,您是否尝试在驱动程序选项中添加 page_load_strategy = ‘eager’?我意识到等待所有内容加载会导致 Heroku 偶尔抛出超时错误(这可能是导致我的情况出现页面崩溃错误的原因,很久以前就修复了,记不清了),而只等待 DOM 加载会使我的程序执行速度提高多个数量级

2025-01-03