0

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

Rinael
  • 133
  • 3
  • 12

3 Answers3

0

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
Mahmudul Hasan
  • 241
  • 2
  • 8
  • yes, I am using Mac, and if I don't use OOP approach the path works fine but when I instantiate Booking class it gives the error – Rinael Dec 04 '21 at 12:05
0

You can try this hack by modifying this line

super(Booking, self).__init__()

to this

super(Booking, self).__init__(driver_path)
Mahmudul Hasan
  • 241
  • 2
  • 8
0

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")
West
  • 2,350
  • 5
  • 31
  • 67