I'm trying to run Selenium inside the context of a Flask application running on Apache as a WSGI application inside a venv.
(I strongly suspect the problem is permission-related but can't figure out the solution.)
Flask code
from selenium import webdriver
from selenium.webdriver import FirefoxOptions
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
def create_session():
chrome_options = Options()
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.binary_location="/snap/bin/chromium"
chrome_options.add_argument("--log-path='/path/to/app/geckodriver.log'")
service = Service('/usr/bin/chromedriver')
browser=webdriver.Chrome(service=service, options=chrome_options)
browser.get('https://someaddress.com/login')
Route
@app.route('/test')
def test():
r = create_session()
Error (in apache2/error.log)
[...] [wsgi:error] [...] [client ...] File "/path/to/app/selenium-stuff.py", line 34, in create_session
[...] [wsgi:error] [...] [client ...] browser = webdriver.Firefox(service=service, options=opts)
[...] [wsgi:error] [...] [client ...] File "/path/to/app/venv/lib/python3.10/site-packages/selenium/webdriver/firefox/webdriver.py", line 61, in __init__
[...] [wsgi:error] [...] [client ...] self.service.start()
[...] [wsgi:error] [...] [client ...] File "/path/to/app/venv/lib/python3.10/site-packages/selenium/webdriver/common/service.py", line 97, in start
[...] [wsgi:error] [...] [client ...] self.assert_process_still_running()
[...] [wsgi:error] [...] [client ...] File "/path/to/app/venv/lib/python3.10/site-packages/selenium/webdriver/common/service.py", line 110, in assert_process_still_running
[...] [wsgi:error] [...] [client ...] raise WebDriverException(f"Service {self._path} unexpectedly exited. Status code was: {return_code}")
[...] [wsgi:error] [...] [client ...] selenium.common.exceptions.WebDriverException: Message: Service /snap/bin/geckodriver unexpectedly exited. Status code was: 1
I've tried --
- ensuring headless
- switching to chromium (chrome-driver)
geckodriver.log exists, has had chmod +w, but doesn't hold much in the way of logging. /snap/bin/geckodriver similarly exists and should be globally executable.
The function works perfectly well when (a) called directly through python3 on the command line, or (b) called through the Flask development webserver, but not when used in Apache/WSGI. Hence why I suspect a permissions issue...
edit...
Tried running /usr/bin/chromedriver as normal, non-privileged (i.e. non-root) user -- works fine. Tried running sudo -u www-data /usr/bin/chromedriver
and got the following:
/user.slice/user-1000.slice/session-2.scope is not a snap cgroup
so it looks like chromedriver can't be run as user www-data. I tried disabling (temporarily!) apparmor.service, but that made no difference.
Solution?
I eventually gave up with chromium/chromedriver and went back to firefox.
It's not a tidy solution, but ... following (post #13 here) suggested reinstalling firefox with developer mode enabled, which circumvents some of the sandboxing permission issues... which appears to have worked.