python selenium下载一个合适的chromedriver.exe(稳定版本)
可以使用该脚本来进行下载:
下载前需要安装如下的依赖
requests==2.27.1
selenium==4.14.0
webdriver_manager==4.0.1
下载脚本代码:
import json
import subprocess
import shutil
import os
import time
import zipfileimport requests
from webdriver_manager.core.os_manager import OperationSystemManager
from webdriver_manager.chrome import ChromeDriverManager, ChromeType__all__ = {'download_suit_chrome_driver'
}# 记录固定数据
chrome_json_file = 'chrome_version.json'
chrome_zip = 'chrome_driver.zip'def format_float(num):return '{:.2f}'.format(num)def download_file(name, url):''':param name:下载保存的名称:param url: 下载链接:return:'''headers = {'Proxy-Connection': 'keep-alive'}r = requests.get(url, stream=True, headers=headers)length = float(r.headers['content-length'])f = open(name, 'wb')count = 0count_tmp = 0time1 = time.time()for chunk in r.iter_content(chunk_size=512):if chunk:f.write(chunk)count += len(chunk)if time.time() - time1 > 2:p = count / length * 100speed = (count - count_tmp) / 1024 / 1024 / 2count_tmp = countprint(name + ': ' + format_float(p) + '%' + ' Speed: ' + format_float(speed) + 'M/S')time1 = time.time()f.close()def install_chrome_driver():"""安装chrome浏览器"""try:p = ChromeDriverManager(chrome_type=ChromeType.CHROMIUM).install()os.environ['CHROME_DRIVER_PATH'] = pexcept Exception as e:print("error")def get_chromedriver_version(chromedriver_path="chromedriver.exe"):"""获取chrome_driver版本Args:chromedriver_path:Returns:"""try:# 运行Chromedriver,并通过命令行参数获取版本信息result = subprocess.run([chromedriver_path, '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)if result.returncode == 0:# 如果成功执行,解析版本信息version = result.stdout.strip()version_list = str(version).split(" ")if len(version_list) == 3:version = version_list[1]return True, versionelse:# 如果执行失败,输出错误信息error_message = result.stderr.strip()return False, f"Error: {error_message}"except Exception as e:return False, f"An error occurred: {str(e)}"def get_chrome_version():"""获取chrome版本Returns:"""try:os_version = OperationSystemManager().get_browser_version_from_os("google-chrome")print(f"os_version:{os_version}")return os_versionexcept Exception as e:return Nonedef get_chrome_version_info(version_info: str):if os.path.exists(chrome_json_file):with open(chrome_json_file) as f:data = f.read()json_data = json.loads(data)if json_data.get(version_info, None) is not None:return True, json_data.get(version_info)else:dict_version_info = {}google_driver_json_url = 'https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json'res = requests.get(google_driver_json_url)res_dict = json.loads(res.text)version_list = res_dict['versions']for version in version_list:downloads_ = version['downloads']if downloads_.get('chromedriver', None) is not None:download_list = downloads_['chromedriver']for data in download_list:if data['platform'] == 'win64':version_place = str(version['version'])version_ = version_place[0:version_place.rfind('.')]dict_version_info[version_] = data['url']with open(chrome_json_file, 'w+') as f:json.dump(dict_version_info, f, indent=4)if dict_version_info.get(version_info, None) is not None:version_url = dict_version_info[version_info]return True, version_urlreturn False, 'error to get'else:dict_version_info = {}google_driver_json_url = 'https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json'res = requests.get(google_driver_json_url)res_dict = json.loads(res.text)version_list = res_dict['versions']for version in version_list:downloads_ = version['downloads']if downloads_.get('chromedriver', None) is not None:download_list = downloads_['chromedriver']for data in download_list:if data['platform'] == 'win64':version_place = version['version']version_ = version_place[0:version_place.rfind('.')]dict_version_info[version_] = data['url']with open(chrome_json_file, 'w+') as f:json.dump(dict_version_info, f, indent=4)if dict_version_info.get(version_info, None) is not None:version_url = dict_version_info[version_info]return True, version_urlreturn False, 'error to get'def download_suit_chrome_driver(chrome_driver_path: str = "chromedriver.exe"):"""下载合适的chrome_driver.exeReturns:"""is_ok, chrome_driver_version = get_chromedriver_version(chrome_driver_path)browser_version = get_chrome_version()if is_ok:if str(chrome_driver_version).count(browser_version) > 0:print(f"当前已是合适的chrome_driver:{chrome_driver_version}")return Trueelse:chrome_driver_big_version = browser_version.split(".")[0]if int(chrome_driver_big_version) < 115:print("下载Chrome-Driver")install_chrome_driver()else:is_get_chrome, version_info = get_chrome_version_info(browser_version)if is_get_chrome:download_url = version_infoprint('ok-remove-0')if os.path.exists(chrome_zip):os.remove(chrome_zip)print('ok-remove-2')download_file(chrome_zip, download_url)print('ok-remove-3')with zipfile.ZipFile(chrome_zip, 'r') as zip_ref:zip_ref.extractall('./')shutil.move('./chromedriver-win64/chromedriver.exe', './chromedriver.exe')if os.path.exists(chrome_zip):os.remove(chrome_zip)else:chrome_driver_big_version = browser_version.split(".")[0]if int(chrome_driver_big_version) < 115:print("下载Chrome-Driver")install_chrome_driver()else:is_get_chrome, version_info = get_chrome_version_info(browser_version)if is_get_chrome:download_url = version_infoprint('ok-remove-0')if os.path.exists(chrome_zip):os.remove(chrome_zip)print('ok-remove-2')download_file(chrome_zip, download_url)print('ok-remove-3')with zipfile.ZipFile(chrome_zip, 'r') as zip_ref:zip_ref.extractall('./')shutil.move('./chromedriver-win64/chromedriver.exe', './chromedriver.exe')if os.path.exists(chrome_zip):os.remove(chrome_zip)if __name__ == '__main__':download_suit_chrome_driver("chromedriver.exe")
调用方式:
download_suit_chrome_driver("xxxxx") ## xxxxxx表示chrome_driver.exe路径(可为空)
github下载链接: https://github.com/huifeng-kooboo/download_chrome_driver
相关文章:
python selenium下载一个合适的chromedriver.exe(稳定版本)
可以使用该脚本来进行下载: 下载前需要安装如下的依赖 requests2.27.1 selenium4.14.0 webdriver_manager4.0.1下载脚本代码: import json import subprocess import shutil import os import time import zipfileimport requests from webdriver_mana…...

RabbitMQ从0到1完整学习笔记一:《基础篇》
目录 启篇 一、初识MQ 1.1 同步调用 1.2异步调用 1.3 技术选型 二、RabbitMQ 架构 2.2 收发消息 2.2.1 交换机 2.2.2 队列 2.2.3 绑定关系 2.2.4 发送消息 2.3 数据隔离 2.3.1 用户管理 2.3.2 virtual host 三、SpringAMQP 3.1 案例入门 3.1.1 导入依赖 3.1.2 消息发送 3.1.2 消…...
什么是时间冒泡?
时间冒泡是指当一个元素触发一个事件时,事件会像水泡一样,从触发元素向它的所有父节点传播,一直到根节点都会接收到此事件 1。如果父元素中注册了相应的事件处理函数,那么尽管事件在子节点触发的,在父元素上注册的事件…...

Go语言入门心法(三): 接口
Go语言入门心法(一) Go语言入门心法(二): 结构体 Go语言入门心法(三): 接口 一:go语言接口认知 Go语言中接口认知升维:解决人生问题的自我引导法则: 复盘思维|结构化思维|金字塔思维|体系化思维|系统化思维 面向对象编程(oop)三大特性: 封装,继承,多态 Go语言中,可…...
leetcode:210. 课程表 II
课程表 II 提示 中等 889 相关企业 现在你总共有 numCourses 门课需要选,记为 0 到 numCourses - 1。给你一个数组 prerequisites ,其中 prerequisites[i] [ai, bi] ,表示在选修课程 ai 前 必须 先选修 bi 。 例如,想要学习课程…...
[MT8766][Android12] 使用谷歌LPA实现ESIM功能的流程
文章目录 开发平台基本信息问题描述实现流程 其他问题 开发平台基本信息 芯片: MT8766 版本: Android 12 kernel: msm-4.19 问题描述 客户需要我们设备支持ESIM功能,5月份的时候在高通6125上面预研过ESIM功能,当时ESIM供应商是Links field,…...

MyBatis-Plus为简化开发而生
简介 MyBatis-Plus 简称 MP是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 他们的愿景是成为 MyBatis 最好的搭档,就像魂斗罗中的 1P、2P,基友搭配,效率翻倍。 特性 无…...

【翻译】Efficient Data Loader for Fast Sampling-Based GNN Training on Large Graphs
转载请注明出处:小锋学长生活大爆炸[xfxuezhang.cn] 此内容为机器翻译的结果,若有异议的地方,建议查看原文。 机器翻译的一些注意点,比如: 纪元、时代 > epoch工人 > worker火车、培训、训练师 > train Effic…...
OPUS解码器PLC
OPUS解码器支持PLC(Packet Loss Concealment)技术。 在音频通信中,网络丢包是常见的情况。当网络丢失一些音频数据包时,接收端可能无法正常解码并播放这些丢失的音频信号,导致声音中断或质量下降。为了改善这种情况&a…...

Rancher 使用指南
Rancher 使用指南 Rancher 是什么?Rancher 与 OpenShift / Kubesphere 主要区别对比RancherOpenShiftKubesphere 对比 Rancher 和 OpenShift Rancher 安装 Rancher 是什么? 企业级Kubernetes管理平台 Rancher 是供采用容器的团队使用的完整软件堆栈。它解决了管理多个Kuber…...

百度SEO优化全攻略(提高网站排名的5个方面)
百度SEO入门介绍: 随着互联网的不断发展,SEO已经成为网站优化的重要一环。而百度作为中国最大的搜索引擎,其SEO优化更是至关重要。SEO不仅能够提高网站排名,还能够提高网站流量、用户体验以及品牌知名度。因此,掌握百…...

华为云云耀云服务器L实例评测|华为云耀云服务器L实例私有库搭建verdaccio(八)
九、华为云耀云服务器L实例私有库搭建verdaccio: Verdaccio 是一个简单的、零配置本地私有 npm 软件包代理注册表。Verdaccio 开箱即用,拥有自己的小型数据库,能够代理其它注册表(例如 npmjs.org),缓存下载…...

C语言之动态内存管理_柔性数组篇(2)
目录 柔性数组的特点 柔性数组的使用 动态内存函数增容柔性数组模拟实现 柔性数组的优势 今天接着来讲解一下柔性数组知识。 柔性数组的特点 C99中,结构中的最后一个元素允许是未知大小的数组,这就叫做【柔性数组】成员。 结构体中最后一个成员未…...
vue基础
引入vue文件 <div id"app"><!--{{}}插值表达式,绑定vue中的data数据-->{{message}} </div><script src"vue.min.js"></script> <script>new Vue({el:#app,data:{message:Hello Vue}}) </script>单项…...

访问量突破1W,纪念一下~
Mr.kanglong, 继续加油!...
C# 处理TCP数据的类(服务端)
using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Threading;namespace TestDemo {/// <summary>/// 处理TCP数据的类(服务端)/// </summary>public class TcpService{/// <s…...

【Jenkins】调用API构建并钉钉通知
文章目录 Jenkins API介绍提交作业带参数的作业API 令牌 Shell调用代码 Jenkins API介绍 Jenkins 提供了远程访问 API。目前它有三种格式: XML JSON Python 远程访问 API 形式为"…/api/" 例如, Jenkins 安装位于https://ci.jenkins.io&a…...
Java NIO三大核心组件
文章目录 一、Buffer1、重要属性2、重要方法1)allocate()创建缓冲区2)put()写入到缓冲区3)flip()翻转4)get()从缓冲区读取5)rewind()倒带6)mark()和reset()7)clear()清空缓冲区8)使用…...
js数据排序方法(sort)?
在JavaScript中,可以使用Array的sort()方法对数据进行排序。下面是一个基本的例子,它展示了如何对一个数组进行升序和降序排序: // 创建一个数字数组 let numbers [2, 9, 1, 5, 8, 6];// 升序排序 let ascending numbers.sort(function(a,…...
若依框架学习笔记_mybatis
一、 在框架中引用的先后顺序 在ruoyi-system的resources下的xml中定义方法在java下的mapper包中引用方法在java下的service包中再引用mapper的方法 二、xml中的写法 标签: resultMap 返回数据sql 查询语句 可包含在其他操作中select 查询insert 插入update 更新…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...

windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...

高考志愿填报管理系统---开发介绍
高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发,采用现代化的Web技术,为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## 📋 系统概述 ### 🎯 系统定…...