关于selenium, 你还在因为chromedriver的版本与Chrome的版本不一致,需要手动更新chromedriver而烦恼吗?
前言
平时做爬虫我比较喜欢用
selenium chrome
,一直困扰我一个问题,就是只要谷歌浏览器更新了,就要重新去下载对应版本的chromedriver_win32
,这让我十分烦恼比如我的谷歌浏览器已经94版本了,但是
chromedriver_win32
还停留在92版本,就会报出下面的错误selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 92
Current browser version is 94.0.4606.71 with binary path C:\Program Files (x86)\Google\Chrome\Application\chrome.exe下面就解决这个痛点,实现自动下载和本地谷歌浏览器匹配的
chromedriver_win32
文章目录
- 前言
- selenium基本代码,抛出问题
- 实现自动下载匹配的chromedriver ,解决问题
- 问题1,怎么获取本地谷歌浏览器的版本?
- 问题2,怎么知道本地的 `chromedriver_win32`版本不匹配?
- 问题3,怎么下载最新的`chromedriver.exe`?
- 问题4,下载的怎么解压并换掉旧版`?
- 完善selenium主代码
- 总结
selenium基本代码,抛出问题
① 我们新建一个selenium_test.py
,下面代码是打开百度页面的基本selenium代码,
from selenium import webdriver
import timeclass MySelenium(object):def __init__(self):self.basic_url = "https://www.baidu.com/"self.executable_path = r"./chromedriver_win32/chromedriver.exe"@propertydef start_driver(self):self.browser = webdriver.Chrome(executable_path=self.executable_path)self.browser.maximize_window()def request_url(self, url):""":param url:"""self.browser.get(url)
if __name__ == '__main__':start_time = time.time()ms = MySelenium()ms.start_driverms.request_url(ms.basic_url)#ms.close()test_time = time.strftime("%H:%M:%S", time.gmtime(time.time() - start_time))print(test_time)
② 因为这个代码是我在很早之前写的,当时本地的谷歌浏览器版本还是92,现在已经升级到94了,于是就报了下面的错误,就是版本不匹配
selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 92
Current browser version is 94.0.4606.71 with binary path C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
实现自动下载匹配的chromedriver ,解决问题
问题1,怎么获取本地谷歌浏览器的版本?
①,一般获取本地应用的版本信息,用的都是win32com
库的接口,新建文件 download_driver.py
具体代码如下
- 请先知道谷歌浏览器在本地的安装位置,代码中列出来一般情况,特殊安装位置要加进列表
local_chrome_paths
from win32com.client import Dispatch
class auto_download_chromedrive(object):def __init__(self):self.local_chrome_paths = [r"C:\Program Files\Google\Chrome\Application\chrome.exe",r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"]def get_version_via_com(self, filename):parser = Dispatch("Scripting.FileSystemObject")try:version = parser.GetFileVersion(filename)except Exception:return Nonereturn versiondef start(self):version = list(filter(None, [self.get_version_via_com(p) for p in self.local_chrome_paths]))[0]if not version:print("check chrome browser version failed!")return Noneprint("chrome browser version:", version)if __name__ == "__main__":chrome = auto_download_chromedrive()chrome.start()
②,输出结果可以得到本地浏览器的版本是94版本的。
问题2,怎么知道本地的 chromedriver_win32
版本不匹配?
①,我们再看下chrome不匹配的报错,具体的报错位SessionNotCreatedException
我们修改下selenium
的脚本,加上
try except捕捉这个错误
- 更改下
selenium_test.py
文件的脚本, 导入SessionNotCreatedException
用try
,捕捉到这个报错return 0
from selenium import webdriver
from selenium.common.exceptions import SessionNotCreatedException #导入SessionNotCreatedException
import timeclass MySelenium(object):def __init__(self):self.basic_url = "https://www.baidu.com/"self.executable_path = r"./chromedriver_win32/chromedriver.exe"@propertydef start_driver(self):try:self.browser = webdriver.Chrome(executable_path=self.executable_path)self.browser.maximize_window()except SessionNotCreatedException:print("Chrome version unmatch. ")return 0return 1
问题3,怎么下载最新的chromedriver.exe
?
①,首先肯定不能用selenium
了,这里我选择了requests
和 lxml
库完成下载任务
如下图 chromedriver.exe 下载地址 和页面结构
②,更新download_driver.py
,添加一个函数 get_chromedriver_urls
,用来解析页面
from win32com.client import Dispatch
import requests
from lxml import etree
class auto_download_chromedrive(object):def __init__(self):self.chromedrive_url = "https://chromedriver.chromium.org/downloads"self.local_chrome_paths = [r"C:\Program Files\Google\Chrome\Application\chrome.exe",r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"]self.headers = {'content-type': 'application/json','User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0'}def get_version_via_com(self, filename):parser = Dispatch("Scripting.FileSystemObject")try:version = parser.GetFileVersion(filename)except Exception:return Nonereturn versiondef get_chromedriver_urls(self):try:r = requests.Session()response = r.get(self.chromedrive_url, headers=self.headers)print(response.status_code, response.encoding)html = etree.HTML(response.text, etree.HTMLParser()) # 解析HTML文本内容version_href = html.xpath(".//strong//..//@href")return version_hrefexcept Exception:return Nonedef start(self):'''读取本地chrome version'''version = list(filter(None, [self.get_version_via_com(p) for p in self.local_chrome_paths]))[0]if not version:print("check chrome browser version failed!")return Noneprint("chrome browser version:", version)'''下载网页端与本地匹配的chromedriver.exe'''version_href = self.get_chromedriver_urls()if not version_href:print("request %s failed!"%self.chromedrive_url)return Noneprint("all chrome browser versions can be choosed:\n{}".format(version_href))if __name__ == "__main__":chrome = auto_download_chromedrive()chrome.start()
③,输出结果如下图,得到所有的chromedriver
的下载地址
休息下1分钟。。。
④,更新download_driver.py
,目的是在所有的版本中找到本地浏览器匹配的版本,并下载下来
- 新加函数
find_local_version
,在所有的版本中找到本地浏览器匹配的版本 - 然后删减和拼接下url,组成新的url,直指
chromedriver_win32.zip
- 新加函数
download_chromadrive
,根据上面的url,下载指定版本
from win32com.client import Dispatch
import re
import requests
from lxml import etree
class auto_download_chromedrive(object):def __init__(self):self.chromedrive_url = "https://chromedriver.chromium.org/downloads"self.local_chrome_paths = [r"C:\Program Files\Google\Chrome\Application\chrome.exe",r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"]self.headers = {'content-type': 'application/json','User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0'}def get_version_via_com(self, filename):parser = Dispatch("Scripting.FileSystemObject")try:version = parser.GetFileVersion(filename)except Exception:return Nonereturn versiondef get_chromedriver_urls(self):try:r = requests.Session()response = r.get(self.chromedrive_url, headers=self.headers)print(response.status_code, response.encoding)html = etree.HTML(response.text, etree.HTMLParser()) # 解析HTML文本内容version_href = html.xpath(".//strong//..//@href")print("all chrome browser versions can be choosed:")for href in version_href:print(href)return version_hrefexcept Exception:return Nonedef download_chromadrive(self, url):try:r = requests.Session()response = r.get(url, headers=self.headers)if response.status_code == 200:with open("chromedriver_win32.zip", "wb") as f:f.write(response.content)print("下载完成")return 1else:print('Url请求返回错误,错误码为: %d' % response.status_code)return Noneexcept Exception:print("request download chromedriver_win32.zip failed!")return Nonedef find_local_version(self, loc_ver, all_ver):""":param loc_ver: 本地浏览器的版本:param all_ver: 下载的所有版本浏览器版本:return: 找到匹配的,return url,否则return None"""for href in all_ver:try:res = re.search(r"path=(.*?)/", href)find_ver = res.group(1).split(".")[0] #截取大版本if loc_ver == find_ver:return hrefexcept Exception:continueprint("not find match chrome browser{} version!".format(loc_ver))return Nonedef start(self):'''读取本地chrome version'''version = list(filter(None, [self.get_version_via_com(p) for p in self.local_chrome_paths]))[0]if not version:print("check chrome browser version failed!")return Noneprint("chrome browser version:", version)'''下载网页端与本地匹配的chromedriver.exe'''version_href = self.get_chromedriver_urls()if not version_href:print("request %s failed!"%self.chromedrive_url)return None'''找到'''find_url = self.find_local_version(version.split(".")[0], version_href)print("找到匹配的版本:\n%s"%find_url)if not find_url:return Noneversion_num = re.search(r"path=(.*?)/", find_url).group(1)find_url_2 = find_url.rsplit('/', 2)[0]new_url = "{}/{}/chromedriver_win32.zip".format(find_url_2, version_num)print("downloading......\n%s"%new_url)ret = self.download_chromadrive(new_url)if not ret:return Noneif __name__ == "__main__":chrome = auto_download_chromedrive()chrome.start()
⑤,输出结果如下图
问题4,下载的怎么解压并换掉旧版`?
①,直接删除是肯定不行的,因为,当你使用过selenium
之后,必须要在进程找那个杀掉chromedriver.exe才可以替换掉旧版本的。
- 定义一个新函数
kill_process
,如果进程中存在chromedriver.exe
就杀掉
def kill_process(self, process_name):print("检测{}进程是否存在,存在则杀掉。".format(process_name))pl = psutil.pids()for pid in pl:if psutil.Process(pid).name() == process_name:print('{} 存在进程中,杀掉'.format(process_name))os.popen('taskkill /f /im %s' %process_name)return pidprint('{} 不存在进程中。'.format(process_name))return None
- 下面一段代码是清除chromedriver_win32文件夹内文件的只读属性(因为我的代码从托管平台同步后就只读了)
old_driver_path = os.path.join(os.getcwd(), "chromedriver_win32")if os.path.exists(old_driver_path):for sub_file in os.listdir(old_driver_path):os.chmod(os.path.join(old_driver_path, sub_file), stat.S_IRWXU)time.sleep(1) #这个delay必须要有,os操作还是需要时间的
- 下面一段代码解压新版本的
chromedriver
,替换掉旧版本
print('''解压 chromedriver_win32.zip,覆盖旧版本''')zFile = zipfile.ZipFile(os.path.join(os.getcwd(), "chromedriver_win32.zip"), "r")for fileM in zFile.namelist():zFile.extract(fileM, old_driver_path)zFile.close()
download_driver.py
完整代码如下:
from win32com.client import Dispatch
import re
import stat,zipfile,os,psutil
import requests
from lxml import etree
import timeclass auto_download_chromedrive(object):def __init__(self):self.chromedrive_url = "https://chromedriver.chromium.org/downloads"self.local_chrome_paths = [r"C:\Program Files\Google\Chrome\Application\chrome.exe",r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"]self.headers = {'content-type': 'application/json','User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0'}def get_version_via_com(self, filename):parser = Dispatch("Scripting.FileSystemObject")try:version = parser.GetFileVersion(filename)except Exception:return Nonereturn versiondef get_chromedriver_urls(self):try:r = requests.Session()response = r.get(self.chromedrive_url, headers=self.headers)print(response.status_code, response.encoding)html = etree.HTML(response.text, etree.HTMLParser()) # 解析HTML文本内容version_href = html.xpath(".//strong//..//@href")print("all chrome browser versions can be choosed:")for href in version_href:print(href)return version_hrefexcept Exception:return Nonedef download_chromadrive(self, url):try:r = requests.Session()response = r.get(url, headers=self.headers)if response.status_code == 200:with open("chromedriver_win32.zip", "wb") as f:f.write(response.content)print("下载完成")return 1else:print('Url请求返回错误,错误码为: %d' % response.status_code)return Noneexcept Exception:print("request download chromedriver_win32.zip failed!")return Nonedef find_local_version(self, loc_ver, all_ver):""":param loc_ver: 本地浏览器的版本:param all_ver: 下载的所有版本浏览器版本:return: 找到匹配的,return url,否则return None"""for href in all_ver:try:res = re.search(r"path=(.*?)/", href)find_ver = res.group(1).split(".")[0] #截取大版本if loc_ver == find_ver:return hrefexcept Exception:continueprint("not find match chrome browser{} version!".format(loc_ver))return Nonedef kill_process(self, process_name):print("检测{}进程是否存在,存在则杀掉。".format(process_name))pl = psutil.pids()for pid in pl:if psutil.Process(pid).name() == process_name:print('{} 存在进程中,杀掉'.format(process_name))os.popen('taskkill /f /im %s' %process_name)return pidprint('{} 不存在进程中。'.format(process_name))return Nonedef unzip(self):self.kill_process("chromedriver.exe")print("去除旧版本chromedriver_win32文件夹内文件的只读属性(如果是只读)")old_driver_path = os.path.join(os.getcwd(), "chromedriver_win32")if os.path.exists(old_driver_path):for sub_file in os.listdir(old_driver_path):os.chmod(os.path.join(old_driver_path, sub_file), stat.S_IRWXU)time.sleep(1) #这个delay必须要有,os操作还是需要时间的print('''解压 chromedriver_win32.zip,覆盖旧版本''')zFile = zipfile.ZipFile(os.path.join(os.getcwd(), "chromedriver_win32.zip"), "r")for fileM in zFile.namelist():zFile.extract(fileM, old_driver_path)zFile.close()def start(self):'''读取本地chrome version'''version = list(filter(None, [self.get_version_via_com(p) for p in self.local_chrome_paths]))[0]if not version:print("check chrome browser version failed!")return Noneprint("chrome browser version:", version)'''下载网页端与本地匹配的chromedriver.exe'''version_href = self.get_chromedriver_urls()if not version_href:print("request %s failed!"%self.chromedrive_url)return Nonefind_url = self.find_local_version(version.split(".")[0], version_href)print("找到匹配的版本:\n%s"%find_url)if not find_url:return Noneversion_num = re.search(r"path=(.*?)/", find_url).group(1)find_url_2 = find_url.rsplit('/', 2)[0]new_url = "{}/{}/chromedriver_win32.zip".format(find_url_2, version_num)print("downloading......\n%s"%new_url)ret = self.download_chromadrive(new_url)if not ret:return Noneself.unzip()
if __name__ == "__main__":chrome = auto_download_chromedrive()chrome.start()
真舒服。。。
完善selenium主代码
我们只需要在selenium_test.py
中引用download_driver.py
中的auto_download_chromedrive
类即可
源码我放在git上,如需自取
from selenium import webdriver
from selenium.common.exceptions import SessionNotCreatedException #导入NoSuchElementException
import time
from download_driver import auto_download_chromedriveclass MySelenium(object):def __init__(self):self.basic_url = "https://www.baidu.com/"self.executable_path = r"./chromedriver_win32/chromedriver.exe"@propertydef start_driver(self):try:self.browser = webdriver.Chrome(executable_path=self.executable_path)self.browser.maximize_window()except SessionNotCreatedException:print("Chrome version unmatch. ")return Nonereturn 1def request_url(self, url):self.browser.get(url)if __name__ == '__main__':start_time = time.time()ms = MySelenium()if not ms.start_driver:chrome = auto_download_chromedrive()chrome.start()ms.start_driverms.request_url(ms.basic_url)#ms.close()test_time = time.strftime("%H:%M:%S", time.gmtime(time.time() - start_time))print(test_time)
源码我放在git上,如需自取
总结
- 本博客谢绝转载
- 要有最朴素的生活,最遥远的梦想,即使明天天寒地冻,路遥马亡!
- 如果这篇博客对你有帮助,请 “点赞” “评论”“收藏”一键三连 哦!码字不易,大家的支持就是我坚持下去的动力。当然执意选择白嫖也常来哈。
关于selenium, 你还在因为chromedriver的版本与Chrome的版本不一致,需要手动更新chromedriver而烦恼吗?相关推荐
- 使用Selenium时,如何选择ChromeDriver驱动版本对应Chrome浏览器版本
参考 http://chromedriver.storage.googleapis.com/index.html
- 根据本地浏览器的版本自动更新chromedriver
webdriver-manager 是一个 Python 库,它可以自动下载和管理 Webdriver 驱动程序,包括 ChromeDriver.GeckoDriver.EdgeDriver.IEDr ...
- 已解决selenium.common.exceptions.WebDriverException: Message: unknown error: cannot find Chrome binary
已解决selenium.common.exceptions.WebDriverException: Message: unknown error: cannot find Chrome binary ...
- mac本更新chromedriver版本
1.chromedriver的版本要和chrome的版本保持一致,如果chrome的版本升级了 chromedriver也要升级,否则执行web自动化会登录失败 2.因chromedriver的官网打 ...
- Selenium 与(Firefox、GeckoDriver)和(Chrome、ChromeDriver)版本对应关系
找了一圈,竟然一个靠谱的版本对应表都找不到,这里整理一下 下载地址 Selenium ChromeDriver Chrome GeckoDriver Firefox Selenium Firefox ...
- chromedriver与chrome各版本及下载地址,截止到2018.5.30
下载地址 https://chromedriver.storage.googleapis.com/index.html 官网2.3.9版本打开后点击notes.txt文件打开后看到 对应版本 ---- ...
- Chrome的版本和Selenium支持的版本不一致
chrome的版本和Selenium支持的版本不一致,报错如下: selenium.common.exceptions.SessionNotCreatedException: Message: ses ...
- 找不到和chrome浏览器版本不同的chromedriver的解决方法
某一天我很久没有chromedriver之后,发现我的google版本是下图这样 打开这个网站下载新版本的chromedriver,我发现没有103.0.5060.114.虽然我不知道为什么没有但是问 ...
- linux下载google chrome,chromedriver,使用webdriver.Chrome()
1.安装google chrome 首先,查看自己Linux是什么系统,系统不同,好像安装也不一样,我的是centos7 cat /etc/redhat-release #查看系统版本 我的安装过程是 ...
最新文章
- c语言四则运算实验报告,c语言四则运算实验报告.doc
- python 内推_网易有道2017内推编程题 洗牌(python)
- how tomcat works 1 simple web server
- SAP ERP项目各模块设计重点
- 快速上手Ubuntu搭建Python编程环境
- java 日期 区间_如何实现时间区间的分割??
- 阿里十年DBA经验产品经理:真的不要再有一起删库跑路事件了
- spring+hibernate+Struts2 整合(全注解及注意事项)
- excel导入导出工具类_Hutool Java工具类库导出Excel,超级简单
- 以太坊代码标准是什么_以太坊:什么是ERC20标准?
- 一步一步写算法(之字符串查找 上篇)
- 查找出现次数 oracle,ORACLE计算某个列中出现次数最多的值
- CocoaPods 安装
- log4j的使用 slf4j简单介绍
- Java实现校园论坛系统
- Twaver-HTML5基础学习(13)连线(Link)连线的绑定与展开
- Vue开发需要的网站
- 【H3C模拟器】配置交换机的链路聚合
- 供应链库存管理-库存控制策略
- 《都挺好》苏大强,锦鲤杨超越,表情包为何会刷屏?