How To Run Selenium With Chrome In Docker

前端 未结 4 1351
孤独总比滥情好
孤独总比滥情好 2021-01-31 04:56

I installed google-chrome in a Docker, but when I run my Python 2 script of Selenium, it failed like this:

automation@1c17781fef0c:/topology-editor/test$ python          


        
相关标签:
4条回答
  • 2021-01-31 05:45

    The best way to use selenium in a docker container you need to do followings.

    Your need to add next lines to your Dockerfile

    # 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==3.8.0
    

    Then your code should be like this. Especially you need to declare your driver like below:

    from selenium import webdriver
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument('--no-sandbox')
    chrome_options.add_argument('--window-size=1420,1080')
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--disable-gpu')
    driver = webdriver.Chrome(chrome_options=chrome_options)
    
    driver.get('www.google.com')
    screenshot = driver.save_screenshot('test.png')
    driver.quit()
    
    0 讨论(0)
  • 2021-01-31 05:54

    I assume you need to run it in headless mode

    https://developers.google.com/web/updates/2017/04/headless-chrome

    this is how I do it in ruby

    capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    chromeOptions: {args: %w[ no-sandbox headless disable-gpu window-size=1280,1000 ]})
    
    Capybara::Selenium::Driver.new(app, :browser => :chrome, http_client: client, desired_capabilities: capabilities)
    

    You can pretty much adapt your code in python

    also consider installing some font libriaries that chrome needs to run on headless

    RUN apt-get update && \
        apt-get -qq -y install  libxpm4 libxrender1 libgtk2.0-0 libnss3\ 
           libgconf-2-4  libpango1.0-0 libxss1 libxtst6 fonts-liberation\ 
           libappindicator1 xdg-utils
    
    RUN apt-get -y install \
                   xvfb gtk2-engines-pixbuf \
                   xfonts-cyrillic xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable \
                   imagemagick x11-apps zip
    
    0 讨论(0)
  • 2021-01-31 05:57

    You need to launch a standalone chrome browser

    docker run -d -p 4444:4444 selenium/standalone-chrome
    

    and then in your python script launch browser using Remote webdriver

    from selenium import webdriver
    from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
    driver = webdriver.Remote("http://127.0.0.1:4444/wd/hub", DesiredCapabilities.CHROME)
    

    If you want you can also launch a Selenium Grid hub.

    To do this as a django test do the following:

    # docker-compse.yml
    
    selenium:
      image: selenium/standalone-firefox
      ports:
      - 4444:4444
    
    # project/app/test.py
    
    from django.test import TestCase
    from selenium import webdriver
    from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
    
    
    class SiteTest(TestCase):
        fixtures = [
            'app/fixtures/app.json',
            ...
        ]
    
        def setUp(self):
            self.browser = webdriver.Remote("http://selenium:4444/wd/hub", DesiredCapabilities.FIREFOX)
    
        def tearDown(self):
            self.browser.quit()
    
        def test_visit_site(self):
            self.browser.get('http://app:8000/')
            self.assertIn(self.browser.title, 'Home')
    

    Note:

    If you use webdriver.ChromeOptions|FirefoxOptions|etc then DesiredCapabalities import is not necessary:

    from selenium import webdriver
    options = webdriver.ChromeOptions()
    options.add_argument('--headless')  # example
    driver = webdriver.Remote("http://127.0.0.1:4444/wd/hub", options=options)
    
    0 讨论(0)
  • 2021-01-31 05:57

    For people coming through google search, here is the easiest workaround:

    Dockerfile

    FROM python:3.7
    
    RUN apt-get update 
    RUN apt-get install -y gconf-service libasound2 libatk1.0-0 libcairo2 libcups2 libfontconfig1 libgdk-pixbuf2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libxss1 fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils
    
    #download and install chrome
    RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
    RUN dpkg -i google-chrome-stable_current_amd64.deb; apt-get -fy install
    
    #install python dependencies
    COPY requirements.txt requirements.txt 
    RUN pip install -r ./requirements.txt 
    
    #some envs
    ENV APP_HOME /app 
    ENV PORT 5000
    
    #set workspace
    WORKDIR ${APP_HOME}
    
    #copy local files
    COPY . . 
    
    CMD exec gunicorn --bind :${PORT} --workers 1 --threads 8 main:app 
    

    You will need to install chromedriver_binary pip package which I have added in requirements.txt as:

    Flask==1.1.1
    gunicorn==20.0.4
    selenium==3.141.0
    chromedriver-binary==79.0.3945.36
    

    Then your main.py should be like:

    from selenium import webdriver
    import chromedriver_binary
    
    
    chrome_options=webdriver.ChromeOptions()
    chrome_options.add_argument("--headless")
    chrome_options.add_argument("--no-sandbox")
    chrome_options.add_argument("window-size=1400,2100") 
    chrome_options.add_argument('--disable-gpu')
    
    driver=webdriver.Chrome(chrome_options=chrome_options)
    

    Now, build your Dockerfile using docker build -t <imagename> . and docker run --rm -p <yourPORT>:5000 <imagename>

    0 讨论(0)
提交回复
热议问题