Home > Software design >  Python Selenium doesn't find chromedriver
Python Selenium doesn't find chromedriver

Time:12-04

I am trying to learn web scraping with Python and Selenium. However, I have been getting an error of FileNotFoundError: [Errno 2] No such file or directory: 'chromedriver' and I am 100% sure that the file is located on the path that I specified as I tried it with much simpler approach before and everything was working fine.

This is my code right now;

class Booking(webdriver.Chrome):
    def __init__(self, driver_path=r"/Users/username/Desktop/SeleniumDriver/chromedriver"):
        self.driver_path = driver_path
        os.environ["PATH"]  = r"/Users/username/Desktop/SeleniumDriver"
        super(Booking, self).__init__()

    def land_first_page(self):
        self.get("https://website.com")


inst = Booking()
inst.land_first_page()

I have tried different many paths with/without r as prefix as well as /chromedriver with exe as an extension or without. Nothing seems to be working. I am getting the error that I mentioned above when instantiating the Booking class

Instead of using OOP if I use the webdriver like this;

os.environ["PATH"]  = r"/Users/username/Desktop/SeleniumDriver"

driver = webdriver.Chrome("/Users/username/Desktop/SeleniumDriver/chromedriver")
driver.get("https://website.com")

It works, and doesn't give me any errors, but I would prefer to use OOP approach as it much more clear for me to work with, especially when creating bots

CodePudding user response:

you must understand about relative and absolute file paths. This will help you to open your chrome-driver. Check out this link hope it will help: Absolute path & Relative Path.

CodePudding user response:

If you're using Mac/Linux, The location is okay

/Users/username/Desktop/SeleniumDriver/chromedriver

If you're using Windows, you may need to specify from the actual drive

C:/Users/username/Desktop/SeleniumDriver/chromedriver

CodePudding user response:

You can try this hack by modifying this line

super(Booking, self).__init__()

to this

super(Booking, self).__init__(driver_path)

CodePudding user response:

Looking at the source code for the __init__ method there is no instance variables initialised there. By that I mean for example there is nothing like self.driver_path = "path".

def __init__(self, executable_path="chromedriver", port=0,
                 options=None, service_args=None,
                 desired_capabilities=None, service_log_path=None,
                 chrome_options=None, keep_alive=True):
        """
        Creates a new instance of the chrome driver.

        Starts the service and then creates new instance of chrome driver.

        :Args:
         - executable_path - path to the executable. If the default is used it assumes the executable is in the $PATH
         - port - port you would like the service to run, if left as 0, a free port will be found.
         - options - this takes an instance of ChromeOptions
         - service_args - List of args to pass to the driver service
         - desired_capabilities - Dictionary object with non-browser specific
           capabilities only, such as "proxy" or "loggingPref".
         - service_log_path - Where to log information from the driver.
         - chrome_options - Deprecated argument for options
         - keep_alive - Whether to configure ChromeRemoteConnection to use HTTP keep-alive.
        """
        if chrome_options:
            warnings.warn('use options instead of chrome_options',
                          DeprecationWarning, stacklevel=2)
            options = chrome_options

        if options is None:
            # desired_capabilities stays as passed in
            if desired_capabilities is None:
                desired_capabilities = self.create_options().to_capabilities()
        else:
            if desired_capabilities is None:
                desired_capabilities = options.to_capabilities()
            else:
                desired_capabilities.update(options.to_capabilities())


        self.service = Service(
            executable_path,
            port=port,
            service_args=service_args,
            log_path=service_log_path)
        self.service.start()

        try:
            RemoteWebDriver.__init__(
                self,
                command_executor=ChromeRemoteConnection(
                    remote_server_addr=self.service.service_url,
                    keep_alive=keep_alive),
                desired_capabilities=desired_capabilities)
        except Exception:
            self.quit()
            raise
        self._is_remote = False

    def launch_app(self, id):
        """Launches Chrome app specified by id."""
        return self.execute("launchApp", {'id': id})

    def get_network_conditions(self):
        """
        Gets Chrome network emulation settings.

        :Returns:
            A dict. For example:

            {'latency': 4, 'download_throughput': 2, 'upload_throughput': 2,
            'offline': False}

        """
        return self.execute("getNetworkConditions")['value']

So in your code the line self.driver_path = driver_path is not doing anything. It sets an instance variable that is not used by the parent class.

You can pass the path in the super statement to make it work:

super().__init__(executable_path = "/Users/username/Desktop/SeleniumDriver/chromedriver")
  • Related