Browse Source

Selenium ChromeDriver Image

This contains chrome headless + chromedriver, and
python browser.py + useragent.py scripts to use this.
Steve Thielemann 3 weeks ago
commit
aa7e883e2f
8 changed files with 264 additions and 0 deletions
  1. 112 0
      chrome-fetch.py
  2. 13 0
      docker-compose.yaml
  3. 18 0
      docker-head.yaml
  4. 13 0
      docker-headless.yaml
  5. 25 0
      requirements.txt
  6. 17 0
      set-bin.sh
  7. 41 0
      show-version.py
  8. 25 0
      ubuntu/Dockerfile

+ 112 - 0
chrome-fetch.py

@@ -0,0 +1,112 @@
+#!/usr/bin/env python3
+
+import requests
+import json
+import os.path
+from pprint import pprint
+
+LATEST = "https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json"
+VERFILE = "version"
+
+r = requests.get(LATEST)
+
+data = r.json()
+stable = data['channels']['Stable']
+version = stable['version']
+update = False
+
+# Check current version against what is available.
+if os.path.exists(VERFILE):
+    with open(VERFILE, "rt") as fp:
+        current_version = fp.readline().strip()
+    print(f"Current version: {current_version}")
+    if current_version != version:
+        update = True
+else:
+    update = True
+
+if update:
+    with open(VERFILE, "wt") as fp:
+        print(f"{version}", file=fp)
+
+print(f"Google Chrome {version}")
+
+if not update:
+    os.sys.exit()
+
+# Ok, we need to update
+
+NEED = ("chrome", "chromedriver")
+grab = list()
+
+# I need chrome and chromedriver for linux64
+for d in stable['downloads']:
+    if d in NEED:
+        # Ok, that's something we need!
+        for platform in stable['downloads'][d]:
+            if platform['platform'] == "linux64":
+                grab.append(platform['url'])
+                break
+
+# Ok, lets grab some files here
+def download_file(url):
+    local_filename = url.split('/')[-1]
+    print(f"Download {url} to {local_filename}")
+    # NOTE the stream=True parameter below
+    with requests.get(url, stream=True) as r:
+        r.raise_for_status()
+        with open(local_filename, 'wb') as f:
+            for chunk in r.iter_content(chunk_size=8192): 
+                # If you have chunk encoded response uncomment if
+                # and set chunk_size parameter to None.
+                #if chunk: 
+                f.write(chunk)
+    print("Done")
+    return local_filename
+
+for g in grab:
+    download_file(g)
+
+# Ok, now what needs to be done?
+# unzip, remove chrome-linux64, chromedriver-linux64 directories.
+# pprint(stable)
+# pprint(grab)
+
+"""
+{'channel': 'Stable',
+ 'downloads': {'chrome': [{'platform': 'linux64',
+                           'url': 'https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.35/linux64/chrome-linux64.zip'},
+                          {'platform': 'mac-arm64',
+                           'url': 'https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.35/mac-arm64/chrome-mac-arm64.zip'},
+                          {'platform': 'mac-x64',
+                           'url': 'https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.35/mac-x64/chrome-mac-x64.zip'},
+                          {'platform': 'win32',
+                           'url': 'https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.35/win32/chrome-win32.zip'},
+                          {'platform': 'win64',
+                           'url': 'https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.35/win64/chrome-win64.zip'}],
+               'chrome-headless-shell': [{'platform': 'linux64',
+                                          'url': 'https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.35/linux64/chrome-headless-shell-linux64.zip'},
+                                         {'platform': 'mac-arm64',
+                                          'url': 'https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.35/mac-arm64/chrome-headless-shell-mac-arm64.zip'},
+                                         {'platform': 'mac-x64',
+                                          'url': 'https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.35/mac-x64/chrome-headless-shell-mac-x64.zip'},
+                                         {'platform': 'win32',
+                                          'url': 'https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.35/win32/chrome-headless-shell-win32.zip'},
+                                         {'platform': 'win64',
+                                          'url': 'https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.35/win64/chrome-headless-shell-win64.zip'}],
+               'chromedriver': [{'platform': 'linux64',
+                                 'url': 'https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.35/linux64/chromedriver-linux64.zip'},
+                                {'platform': 'mac-arm64',
+                                 'url': 'https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.35/mac-arm64/chromedriver-mac-arm64.zip'},
+                                {'platform': 'mac-x64',
+                                 'url': 'https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.35/mac-x64/chromedriver-mac-x64.zip'},
+                                {'platform': 'win32',
+                                 'url': 'https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.35/win32/chromedriver-win32.zip'},
+                                {'platform': 'win64',
+                                 'url': 'https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.35/win64/chromedriver-win64.zip'}]},
+ 'revision': '1415337',
+ 'version': '134.0.6998.35'}
+"""
+
+
+

+ 13 - 0
docker-compose.yaml

@@ -0,0 +1,13 @@
+
+services:
+    selenium:
+      image: selenium
+      build: ubuntu
+      init: true
+      ports: 
+        - "9515:9515"
+      volumes:
+        - "/etc/localtime:/etc/localtime:ro"
+        - "./download:/home/ubuntu/download"
+      user: 1000:1000
+

+ 18 - 0
docker-head.yaml

@@ -0,0 +1,18 @@
+
+services:
+    selenium:
+      image: selenium
+      build: ubuntu
+      init: true
+      ports: 
+        - "9515:9515"
+      # X Display
+      environment:
+        - DISPLAY=${DISPLAY}
+      network_mode: host
+      volumes:
+        - "/etc/localtime:/etc/localtime:ro"
+        - "./download:/home/ubuntu/download"
+        - "/tmp/.X11-unix:/tmp/.X11-unix"
+      user: 1000:1000
+

+ 13 - 0
docker-headless.yaml

@@ -0,0 +1,13 @@
+
+services:
+    selenium:
+      image: selenium
+      build: ubuntu
+      init: true
+      ports: 
+        - "9515:9515"
+      volumes:
+        - "/etc/localtime:/etc/localtime:ro"
+        - "./download:/home/ubuntu/download"
+      user: 1000:1000
+

+ 25 - 0
requirements.txt

@@ -0,0 +1,25 @@
+attrs==25.1.0
+black==25.1.0
+certifi==2025.1.31
+charset-normalizer==3.4.1
+click==8.1.8
+exceptiongroup==1.2.2
+h11==0.14.0
+idna==3.10
+mypy-extensions==1.0.0
+outcome==1.3.0.post0
+packaging==24.2
+pathspec==0.12.1
+platformdirs==4.3.6
+PySocks==1.7.1
+requests==2.32.3
+selenium==4.29.0
+sniffio==1.3.1
+sortedcontainers==2.4.0
+tomli==2.2.1
+trio==0.29.0
+trio-websocket==0.12.2
+typing_extensions==4.12.2
+urllib3==2.3.0
+websocket-client==1.8.0
+wsproto==1.2.0

+ 17 - 0
set-bin.sh

@@ -0,0 +1,17 @@
+#!/bin/bash
+
+echo "Clear out bin..."
+rm -rf ubuntu/bin
+mkdir ubuntu/bin
+echo "Unzip linux64 binary files"
+unzip chrome-linux64.zip -d ubuntu/bin
+unzip chromedriver-linux64.zip -d ubuntu/bin
+echo "Cleanup - remove extra directories"
+cd ubuntu/bin
+mv chrome-linux64/* .
+mv chromedriver-linux64/* .
+rmdir chrome-linux64 chromedriver-linux64
+echo "Ok!  Build the image!"
+
+docker compose build
+

+ 41 - 0
show-version.py

@@ -0,0 +1,41 @@
+#!/bin/env python3
+
+UAFILE = "useragent"
+
+from selenium import webdriver
+
+options = webdriver.ChromeOptions()
+# We're interested in the default useragent, so don't set it here.
+
+options.add_argument("--no-sandbox")
+options.add_argument("--disable-gpu")
+options.add_argument("--disable-dev-shm-usage")
+# options.add_argument("user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36")
+options.add_argument("window-size=1280x1024")
+
+# Ok!  Everything looks good here.  Now to add headless argument option.
+options.add_argument("--headless=new")
+# Headless changes UserAgent from Chrome to HeadlessChrome.
+
+driver = webdriver.Remote(command_executor="http://127.0.0.1:9515", options=options)
+
+ua = driver.execute_script("return navigator.userAgent;")
+
+driver.quit()
+
+print(f"Selenium Google UserAgent={ua}")
+
+ua = ua.replace("HeadlessChrome", "Chrome")
+with open(UAFILE, "wt") as fp:
+    print(f"{ua}", file=fp)
+
+# Create python module to get useragent from.
+# from useragent import USERAGENT
+
+with open("useragent.py", "wt") as fp:
+    print(f'USERAGENT = "{ua}"', file=fp)
+
+# (venv) thor@mount-olympus:~/dev/docker/selenium-chromedriver$ ./show-version.py
+# Selenium Google UserAgent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36
+# (venv) thor@mount-olympus:~/dev/docker/selenium-chromedriver$ ./show-version.py
+# Selenium Google UserAgent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/134.0.0.0 Safari/537.36

+ 25 - 0
ubuntu/Dockerfile

@@ -0,0 +1,25 @@
+# I'd like to use 24.04 and use the default ubuntu user here...
+FROM ubuntu:22.04
+
+# From chromium site, these are the required libs
+# for google chrome for testing to run.
+
+RUN apt update -y && \
+  apt upgrade -y && \
+  apt install -y "libasound2" "libatk-bridge2.0-0" "libatk1.0-0" "libatspi2.0-0" "libc6" "libcairo2" "libcups2" "libdbus-1-3" "libdrm2" "libexpat1" "libgbm1" "libglib2.0-0" "libnspr4" "libnss3" "libpango-1.0-0" "libpangocairo-1.0-0" "libstdc++6" "libudev1" "libuuid1" "libx11-6" "libx11-xcb1" "libxcb-dri3-0" "libxcb1" "libxcomposite1" "libxcursor1" "libxdamage1" "libxext6" "libxfixes3" "libxi6" "libxkbcommon0" "libxrandr2" "libxrender1" "libxshmfence1" "libxss1" "libxtst6" && \
+  apt install -y libxml2 libxslt1.1 libffi8 unzip && \
+  groupadd -g 1000 ubuntu && \
+  useradd -rm -d /home/ubuntu -s /bin/bash -u 1000 -g ubuntu -m ubuntu
+
+# Add google chrome testing to the path.
+ENV PATH="/home/ubuntu/bin:${PATH}"
+
+# Activate user
+USER ubuntu
+WORKDIR /home/ubuntu
+ADD --chown=1000:1000 ./bin/ /home/ubuntu/bin/
+
+# CMD ["chromedriver", "--port=9515", "--whitelisted-ips", "--log-level=INFO"]
+CMD ["chromedriver", "--port=9515", "--whitelisted-ips", "--log-level=WARNING"]
+# Is it working?  This shows you the activity...
+# CMD ["chromedriver", "--port=9515", "--verbose", "--whitelisted-ips"]