0

I am trying to make a standalone executable of a webscraping script that using selenium and webdriver, and I want to be able to share the file to other users without them having to manually install chromedriver and specify its path.

When I run the exectuable with chromedriver in the same directory, I get the following output in terminal:

Traceback (most recent call last):
  File "site-packages/selenium/webdriver/common/service.py", line 76, in start
  File "subprocess.py", line 707, in __init__
  File "subprocess.py", line 1326, in _execute_child
FileNotFoundError: [Errno 2] No such file or directory: 'chromedriver'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "excelRW.py", line 336, in <module>
  File "site-packages/selenium/webdriver/chrome/webdriver.py", line 73, in __init__
  File "site-packages/selenium/webdriver/common/service.py", line 83, in start
selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/chromedriver/home

And in my script, this is what I have for initializing the webdriver:

driver = webdriver.Chrome()

I did find a similar question/answer here: Create a Python executable with chromedriver & Selenium

But I am not sure how to make this work on MacOS; I tried this spec file here, but it gives me that same output as above when I run /dist/excelRW.py:

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None


a = Analysis(['excelRW.py'],
             pathex=['/Users/graememjehovich/Desktop/House Districting Script'],
             binaries=[('/Users/graememjehovich/Desktop/House Districting Script/chromedriver', '**./selenium/webdriver**')],
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          [],
          name='excelRW',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='**excelRW.py**')

1 Answers1

2

Maybe use WebDriverManager, it will download the latest webdriver at runtime, so you do not need to ship it at all. This also solves the issue your users might have when they upgrade their Chrome version, because the Chrome version and the driver need to match. So if you hardcode a version of the driver in your installer the scraper will stop working after the user upgrades their browser, which happens automaticaly with Chrome.

I use it like this:

from webdriver_manager.chrome import ChromeDriverManager
webdriver.Chrome(ChromeDriverManager().install())
Niels van Reijmersdal
  • 2,038
  • 1
  • 20
  • 36