1

I wrote a small automation script using Python and Selenium Web Driver and I made it into an executable and the executable worked fine on my computer but when I tried it on another computer I got that chromedriver isn't in path (note: I included chromedriver using the add binary command and both computers are running the same operating system: Mac OS)

I am not quite sure why this happened, my suspicion is the following:

In my .py code I used the following two lines to initiate the chromedriver

path = "/Users/sergio/chromedriver"
driver = webdriver.Chrome(path)

However, the other computer doesn't even have this path so might be causing it even has this path. Now one might suggest simply using driver = webdriver.Chrome() but here comes the bigger problem: I tried having my chromedriver in a system path like /usr/local/bin and when I did that driver = webdriver.Chrome() worked but compiling the program using pyinstaller didn't work, I ran:
pyinstaller --onefile --noconsole --add-binary 'usr/local/bin/chromedriver:.' finalregtool.py
but I got a lot of errors including Unable to find "/Users/sergio/usr/local/bin/chromedriver" when adding binary and data files

This led to me thinking that pyinstaller automatically adds /Users/sergio to the given path which makes my path wrong so I had to use something inside /Users/sergio , I tried putting my chromedriver in Applications but compilation resulted in not finding the path again, for some reasons compilation worked when the path was /Users/sergio/chromedriver so I went with this path but the code didn't work anymore (chromedriver not found in path) so I had to specify the path manually.

Now I am kind of stuck in a deadlock not knowing what to do. Any help would be appreciated. I hope my explanation was clear enough.

My only end goal is compiling my selenium script and running it on other computers without having them install anything extra, I don't care how this should be done so if anyone has a solution outside pyinstaller I don't mind.

Update: added a bounty

Sergio
  • 275
  • 1
  • 15

5 Answers5

1

There're couple of good solutions for that issue:

1.Install webdriver-manager package:

pip install webdriver-manager

what I prefer mostly and use it like:

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
driver = webdriver.Chrome(ChromeDriverManager().install())

2.Launch Remote Selenium Hub called Selenoid and lauch browser remotely:

driver = webdriver.Remote(command_executor='ip_of_your_selenoid_instance:4444/wd/hub',desired_capabilities=DesiredCapabilities.CHROME)

3.You can launch Chrome docker container and also going to by remote url, what will be always localhost:

driver = webdriver.Remote(command_executor='http://127.0.0.1:4444/wd/hub',desired_capabilities=DesiredCapabilities.CHROME)
Vova
  • 3,117
  • 2
  • 15
  • 23
1

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)

docker-compose:

# docker-compose.yml

selenium:
  image: selenium/standalone-firefox
  ports:
  - 4444:4444
0

pyinstaller unpacks everything into a temporary directory during execution of exe, when using the --onefile mode. Refer to this answer and the related post to get an idea about how to get the correct relative path. You might have to use

path = resource_path("chromedriver")

Also, you can directly add the chromedriver to PATH environment variable in the runtime so you wouldn't have to specify the path explicitly and you can simply call webdriver.Chrome()

os.environ["PATH"] += os.pathsep + resource_path("chromedriver")

pyinstaller conciders usr/local/bin/chromedriver:. as a relative path, thus adds /Users/sergio in an attempt to make it absolute, try using a different location. This location doesn't matter anyway, once this file is found pyinstaller will add this to the root directory of the compiled exe, and unpack it when the exe is executed.

astqx
  • 2,058
  • 1
  • 10
  • 21
0

The modern way to deal with the chromedriver binary is to use WebDriverManager. First you need to install the manager:

pip install webdriver-manager

Then you use it (for Chrome):

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(ChromeDriverManager().install())

In my .NET Core project I use not the most modern approach I have described, but the latest stable NuGet from here https://www.nuget.org/packages/Selenium.WebDriver.ChromeDriver/. Basically the nuget contains the chromedriver and copies it every time to your assembly folder (\bin\Debug\netcoreapp3.1 in my case). This is the line I have in my project:

"<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="*" />"

The star means the latest (highest number) stable package will be used as explained here. Of course you can install the latest version manually, and then on each 2 major Chrome versions to update the NuGet package reference so that is matches your Chrome version. (87 chromedriver works with 87 and 88 Chrome, but not with 89). Then the driver is instantiated with this lines:

var driver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

References:
Error message: "'chromedriver' executable needs to be available in the path" https://www.automatetheplanet.com/webdriver-net50/

K. B.
  • 3,342
  • 3
  • 19
  • 32
  • thank you for this, what about packaging into using pyinstaller? that was the main issue – Sergio Mar 07 '21 at 12:32
  • My suggestion is to try one of the two suggested approaches by me on the original computer. In both cases you do not need to specify a path to chromedriver.exe. That is why I hope that pyinstaller will not have issue with that path. – K. B. Mar 08 '21 at 13:21
0
path = "/Users/sergio/chromedriver"
driver = webdriver.Chrome(path)

Change the above code to the following format

driver = webdriver.Chrome(executable_path='C:/Users/sergio/chromedriver.exe')