docker-python-chromedriver icon indicating copy to clipboard operation
docker-python-chromedriver copied to clipboard

Error: 'chromedriver' executable needs to be in PATH.

Open as3379 opened this issue 5 years ago • 4 comments

I have implemented your dockfile into my project which uses webdriver chrome to run the python test script (using mac OS) . However when tried, it errors out as follows:

image

Docker file:

Use an official Python runtime as a parent image

FROM python:3.7 ENV APP_DIR /app WORKDIR $APP_DIR

ENV PYTHONPATH="$PYTHONPATH:/app"

COPY uits uits COPY requirements.txt requirements.txt COPY setup.py setup.py

install google chrome

RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' RUN apt-get -y update RUN apt-get install -y google-chrome-stable

install chromedriver

RUN apt-get install -yqq unzip RUN wget -O /tmp/chromedriver.zip http://chromedriver.storage.googleapis.com/curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE/chromedriver_linux64.zip RUN unzip /tmp/chromedriver.zip chromedriver -d /usr/local/bin/

set display port to avoid crash

ENV DISPLAY=:99

install selenium

RUN pip install selenium

upgrade pip

RUN pip install --upgrade pip

#install required additional dependencies RUN pip install -r requirements.txt

Test script look like this:

class SeleniumClient(object): """ A wrapper for selenium's client with various handy extensions. """ def init(self, params=None, config="default", driver=None): if driver is not None: self.driver = driver return

    if params['location'] != "local":
        return

    root = os.path.dirname(os.path.realpath(__file__))
    self.logger.info("%s" , _platform)
    if _platform == "darwin":
        user = getpass.getuser()
        download_folder = "/Users/%s/downloads/" % user
    elif "win32" in _platform:
        user = getpass.getuser()
        download_folder = "/Users/%s/downloads/" % user
    elif "linux" in _platform:
        download_folder = "/var/lib/docker"
    else:
        raise NotImplemented("don't know where to save data")
    if "chrome" in config:
        options = webdriver.ChromeOptions()
        preferences = {
            "profile.default_content_settings.popups": 0,
            "download.default_directory": download_folder,
            "credentials_enable_service": 0,
            "profile.password_manager_enabled": 0
        }
        options.add_experimental_option("prefs", preferences)
        if config == "chrome":
            options.add_argument("--start-fullscreen")
        elif config == "chrome_headless":
            options.add_argument('--headless')
            options.add_argument('--disable-gpu')
            options.add_argument("--window-size=1920, 1200")
        self.driver = webdriver.Chrome(executable_path='usr/bin/local',options=options)

as3379 avatar Sep 25 '19 16:09 as3379

There are 2 problems in this script:

  1. The executable path is not correct, it should be /usr/local/bin/chromedriver (but it is actually not required as it should be the default location)
  2. For headless Chrome, --no-sandbox argument is also needed, otherwise it may crash when running

For me I would change the last part of the script like this:

if config == "chrome":
    options.add_argument("--start-fullscreen")
elif config == "chrome_headless":
    options.add_argument('--no-sandbox')
    options.add_argument('--headless')
    options.add_argument('--disable-gpu')
    options.add_argument("--window-size=1920, 1200")
self.driver = webdriver.Chrome(options=options)

Or it should also works with the correct executable path: (make sure it starts with /)

if config == "chrome":
    options.add_argument("--start-fullscreen")
elif config == "chrome_headless":
    options.add_argument('--no-sandbox')
    options.add_argument('--headless')
    options.add_argument('--disable-gpu')
    options.add_argument("--window-size=1920, 1200")
self.driver = webdriver.Chrome(executable_path='/usr/local/bin/chromedriver', options=options)

joyzoursky avatar Oct 18 '19 08:10 joyzoursky

did you resolve this issue?

tried using this in my Dockerfile and even added to path (which may be wrong?) with

RUN export PATH=$PATH:/usr/local/bin/chromedriver

this is the code i'm using:

opts = Options()
    opts.add_argument('--no-sandbox')
    opts.add_argument('--ignore-certificate-errors')
    opts.add_argument('--start-maximized')
    opts.add_argument('--disable-dev-shm-usage')
    #opts.binary_location = '/usr/bin/google-chrome-stable'
    
    with open(creds, 'r') as f:
        creds = json.load(f)

    if headless:
        opts.add_argument('--headless')
        assert opts.headless
        
        def enable_download_headless(browser, download_dir):
            browser.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')
            params = {'cmd':'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': download_dir}}
            browser.execute("send_command", params)
     
        prefs = {
            'download.default_directory': download_path,
            'download.prompt_for_download': False,
            'download.directory_upgrade': True,
            'safebrowsing.enabled': False,
            'safebrowsing.disable_download_protection': True}

    else:
        prefs = {
            'download.prompt_for_download': False,
            'safebrowsing.enabled': False,
            'safebrowsing.disable_download_protection': True}

    opts.add_experimental_option("prefs", prefs)

    browser = Chrome(executable_path = '/usr/local/bin/chromedriver', options = opts)

stevenhurwitt avatar Aug 28 '20 02:08 stevenhurwitt

@stevenhurwitt Could you try with adding these arguments, see if the crash still happens?

opts.add_argument('--no-sandbox')
opts.add_argument('--headless')
opts.add_argument('--disable-gpu')

joyzoursky avatar Aug 28 '20 03:08 joyzoursky

yeah so i think the issue was that it needed to be in the same directory as the script and i needed some additional dependencies for the ubuntu docker container. reference here

stevenhurwitt avatar Aug 28 '20 04:08 stevenhurwitt