Many users of Selenium will encounter a problem. Our Chromedriver is often incompatible with the local Chrome browser version, causing us to fail to instantiate Webdriver.Chrome. The error message is roughly as follows:

An exception occurs: SessionNotCreatedException

Message: session not created: This version of ChromeDriver only supports Chrome version 90 Current browser version is 95.0.4638.69 with binary path C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

There is a third-party professional Python library webdriver_manager that elegantly solves this problem, and its background update of chromedriver uses the official Google chromedriver warehouse. This URL (http://chromedriver.storage.googleapis.com/index.html) can be accessed normally in China. Compared with the Taobao source warehouse, the biggest advantage is that it always has the latest version of chromedriver.

In fact, the webdriver-manager library (installed via pip install webdriver-manager) can also be used to update EdgeChromiumDriver, GeckoDriver, IEDriver, and OperaDriver files. How to do it specifically? In fact, we only need two or three lines of code when we execute it:

1
2
driver_path=ChromeDriverManager().install() 
driver = webdriver.Chrome(executable_path=driver_path)

The source code of the ChromeDriverManager class is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class ChromeDriverManager(DriverManager):
def __init__(self, version="latest",
os_type=utils.os_type(),
path=None,
name="chromedriver",
url="https://chromedriver.storage.googleapis.com",
latest_release_url="https://chromedriver.storage.googleapis.com/LATEST_RELEASE",
chrome_type=ChromeType.GOOGLE,
log_level=logging.INFO,
print_first_line=True,
cache_valid_range=1):
super().__init__(path, log_level=log_level, print_first_line=print_first_line,
cache_valid_range=cache_valid_range)

self.driver = ChromeDriver(name=name,
version=version,
os_type=os_type,
url=url,
latest_release_url=latest_release_url,
chrome_type=chrome_type)

def install(self):
log(f"Current {self.driver.chrome_type} version is {self.driver.browser_version}", first_line=True)
driver_path = self._get_driver_path(self.driver)

os.chmod(driver_path, 0o755)
return driver_path

The source code of the chromedriver class is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class ChromeDriver(Driver):
def __init__(self, name, version, os_type, url, latest_release_url,
chrome_type=ChromeType.GOOGLE):
super(ChromeDriver, self).__init__(name, version, os_type, url,
latest_release_url)
self.chrome_type = chrome_type
self.browser_version = get_browser_version_from_os(chrome_type)

def get_os_type(self):
if "win" in super().get_os_type():
return "win32"
return super().get_os_type()

def get_latest_release_version(self):
log(f"Get LATEST driver version for {self.browser_version}")
resp = requests.get(f"{self._latest_release_url}_{self.browser_version}")
validate_response(resp)
return resp.text.rstrip()

This method calls the find_driver method of the DriverCache class by default:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def find_driver(self, browser_version, driver_name, os_type, driver_version):
metadata = self.get_metadata()

key = f"{os_type}_{driver_name}_{driver_version}_for_{browser_version}"
if key not in metadata:
log(f"There is no [{os_type}] {driver_name} for browser {browser_version} in cache")
return None

driver_info = metadata[key]

if not self.__is_valid(driver_info):
return None

path = driver_info['binary_path']
log(f"Driver [{path}] found in cache")
return path

If the system can find the corresponding version of the driver in a specific path, it can be called directly. Otherwise, the get_latest_release_version method is called to obtain the latest driver online and placed in the corresponding system path.