selenium-自动更新谷歌浏览器驱动

1、简介

selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题,因为有些网页数据是通过JavaScript动态加载的。selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如输入、点击、跳转等,来拿到网页渲染之后的结果,可以支持多种浏览器。

2、环境安装

 2.1、安装selenium库

pip install selenium

2.2、安装浏览器驱动

我一般使用谷歌浏览器,因为谷歌浏览器的检查功能很好用。

1、查看本地Chrome浏览器版本

在浏览器的地址栏输入chrome://version,即可查看浏览器版本号

2、根据浏览器版本号下载对应的驱动程序

驱动程序下载地址:ChromeDriver 下载 - 最新版本 | ChromeDriver 驱动

 下载压缩包后解压到对应的文件夹

2.3、测试

运行下面的python脚本,观察到谷歌浏览器自动打开并且访问百度首页停留10s退出即表示selenium环境安装完成。

import timefrom selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Servicechrome_options = Options()
# 设置浏览器窗口最大化
chrome_options.add_argument("--start-maximized")
# 设置驱动路径
chromedriver_path = '你的chromedriver.exe文件所在的路径'
service = Service(executable_path=chromedriver_path)driver = webdriver.Chrome(service=service, options=chrome_options)url = 'https://www.baidu.com/'driver.get(url)time.sleep(10)driver.quit()

3、自动更新谷歌浏览器驱动

selenium程序的正确运行需要谷歌浏览器和浏览器驱动版本号匹配,由于谷歌浏览器会自动更新导致需要经常手动更换浏览器驱动。

我在网上搜索尝试了很多关闭谷歌浏览器自动更新的办法,一直没有起作用。我们从另一个角度:编写程序自动更新浏览器驱动来解决需要手动更新的问题。

3.1、检查当前谷歌浏览器和浏览器驱动是否匹配

def test_chrome_driver():# 当前谷歌浏览器的驱动路径driver_path = '你的chromedriver.exe文件所在的路径'# 初始化chrome浏览器的选项chrome_options = Options()# 设置浏览器窗口最大化chrome_options.add_argument("--start-maximized")service = Service(executable_path=driver_path)driver = Nonetry:# 创建webdriver对象,传入配置好的options和servicedriver = webdriver.Chrome(service=service, options=chrome_options)url = "https://www.baidu.com/"driver.get(url)print("当前谷歌浏览器版本号和驱动版本号匹配")except Exception as e:# 使用正则表达式从异常信息中提取谷歌浏览器版本号pattern = r"Current browser version is (\d+\.\d+\.\d+\.\d+)"match = re.search(pattern, str(e))if match:browser_version = match.group(1)print(f"当前谷歌浏览器版本号和驱动版本号不匹配,谷歌浏览器版本号为:{browser_version}")return browser_versionfinally:if driver:driver.quit()

匹配运行结果:

不匹配运行结果:

3.2、自动下载对应的谷歌浏览器驱动程序

3.2.1、方法一

解析ChromeDriver 下载 - 最新版本 | ChromeDriver 驱动,找到对应版本的驱动程序下载地址

1、浏览器版本号和驱动版本号不一定完全相同,一般版本号前三部分相同即可。与浏览器版本号前三部分相同的驱动一般有多个,为了保险起见,我们通过一个列表存储可能匹配的驱动程序下载位置。

2、该网站提供适用于不同系统的驱动程序下载地址,我需要的是后缀为"chromedriver-win64.zip"的下载地址,你可以根据需求自行修改。因为可以下载的驱动版本号有多个,所以可以下载的地址也有多个,保存到一个列表中。

def find_chromedriver_url(browser_version):parts1 = browser_version.split('.')url = "https://www.chromedriverdownload.net/zh/"headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36'}response = requests.get(url=url,headers=headers)# 检查请求是否成功if response.status_code == 200:tree = etree.HTML(response.text)# 存储满足浏览器版本号的驱动下标matching_indices = []chromedriver_download_url = []try:h2_div_list = tree.xpath('.//h2[@class="h3"]/text()')for index,h2_item in enumerate(h2_div_list):chromedriver_version = h2_itemmatch_version = re.search(r'\((\d+\.\d+\.\d+\.\d+)\)', chromedriver_version)if match_version:chromedriver_version = match_version.group(1)  # 获取匹配到的版本号parts2 = chromedriver_version.split('.')# 比较前三个部分if parts1[:3] == parts2[:3]:matching_indices.append(index)  # 如果满足条件,将索引添加到结果列表中for index in matching_indices:chromedriver_table = tree.xpath('/html/body//div[@class="row"]//div[@class="manual-article"]/div[@class="article-content"]')[0]target_table = chromedriver_table.xpath(f'./table[{index+1}]')[0]chromedriver_tr_list = target_table.xpath('./tbody/tr')for chromedriver_tr in chromedriver_tr_list:if "chromedriver-win64.zip" in chromedriver_tr.xpath('.//text()')[5]:chromedriver_download_url.append(chromedriver_tr.xpath('.//text()')[5])return chromedriver_download_urlexcept Exception as e:print(f"程序发生了异常:{e}")return Noneelse:print("请求chromedriver下载链接页失败")

3、解压到本地指定文件夹

def download_chromedriver(chromedriver_download_url,browser_version):if chromedriver_download_url:for url in chromedriver_download_url:# 指定保存压缩文件的本地路径zip_file_path = f"chromedriver{browser_version}-win64.zip"# 指定解压后的文件夹路径extract_folder_path = f"chromedriver{browser_version}"try:# 发起请求下载文件headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36'}response = requests.get(url=url,headers=headers)response.raise_for_status()  # 检查请求是否成功# 将下载的文件写入本地with open(zip_file_path, "wb") as file:file.write(response.content)# 创建解压文件夹(如果不存在)if not os.path.exists(extract_folder_path):os.makedirs(extract_folder_path)# 解压文件with zipfile.ZipFile(zip_file_path, "r") as zip_ref:zip_ref.extractall(extract_folder_path)# 获取解压文件夹的子文件夹subfolders = [f for f in os.listdir(extract_folder_path) ifos.path.isdir(os.path.join(extract_folder_path, f))]# 获取子文件夹的路径subfolder_path = os.path.join(extract_folder_path, subfolders[0])# 构造chromedriver.exe的绝对路径chromedriver_path = os.path.join(subfolder_path, "chromedriver.exe")# 检查chromedriver.exe文件是否存在if os.path.exists(chromedriver_path):print("chromedriver.exe的绝对路径为:", chromedriver_path)else:print("子文件夹下没有找到chromedriver.exe文件")print(f"文件已成功下载并解压到 {extract_folder_path} 文件夹中,路径为{chromedriver_path}。")break # 有一个压缩包下载成功即跳出循环except requests.exceptions.RequestException as e:print(f"下载文件时出错:{e}")print("请检查网页链接的合法性,适当重试。")except zipfile.BadZipFile:print("下载的文件不是有效的zip文件。")print("请检查网页链接的合法性,适当重试。")except Exception as e:print(f"发生错误:{e}")

之后将chromedriver_path写入到项目的配置文件中,提供给使用selenium的脚本读取。

3.2.2、方法二

使用webdriver_manager,它的核心功能是自动检测已安装的浏览器版本,并下载匹配的驱动程序。

1、安装方法

pip install webdriver-manager

2、基本使用

from webdriver_manager.chrome import ChromeDriverManager# 安装 ChromeDriver
driver_path = ChromeDriverManager().install()print(driver_path)

此时下载的浏览器驱动、下载位置均为默认,一般情况下直接在selenium创建driver对象时使用,但是会拖慢程序运行速度。

from webdriver_manager.chrome import ChromeDriverManager
from selenium import webdriver# 自动下载并配置ChromeDriver
driver = webdriver.Chrome(ChromeDriverManager().install())# 使用driver进行测试
driver.get("https://www.baidu.com/")
print(driver.title)
driver.quit()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/85690.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java从azure中读取用户信息

以下是用 Java 从 Azure AD 获取用户信息的完整实现方案&#xff0c;使用 Spring Boot 框架和 Microsoft 身份验证库 (MSAL)&#xff1a; 1. 添加 Maven 依赖 <dependencies> <!-- Spring Boot Web --> <dependency> <groupId>org.…

C# 数据库访问与ORM框架全面指南:从ADO.NET到Entity Framework Core

在现代应用开发中&#xff0c;数据持久化是核心需求之一。作为.NET生态系统中的主力语言&#xff0c;C#提供了丰富多样的数据库访问技术和工具。本文将全面探讨C#中的数据库访问方式&#xff0c;重点介绍三种主流ORM&#xff08;对象关系映射&#xff09;框架&#xff1a;Entit…

day19 leetcode-hot100-37(二叉树2)

104. 二叉树的最大深度 - 力扣&#xff08;LeetCode&#xff09; 1.深度优先遍历&#xff08;递归&#xff09;ps:不好理解&#xff0c;所以我一般不喜欢用递归 思路 典型算法&#xff0c;用递归求出高度&#xff0c;每次都是深度优先。 具体算法 /*** Definition for a bi…

【LLMs篇】13:LLaDA—大型语言扩散模型

栏目内容论文标题大型语言扩散模型 (Large Language Diffusion Models)核心思想提出LLaDA&#xff0c;一种基于扩散模型的LLM&#xff0c;通过前向掩码和反向预测过程建模语言分布&#xff0c;挑战自回归模型&#xff08;ARM&#xff09;在LLM领域的主导地位&#xff0c;并展示…

Deepfashion2 数据集使用笔记

目录 数据类别: 筛选类别数据: 验证筛选前2个类别: Deepfashion2 的解压码 数据类别: 类别含义: Class idx类别名称英文名称0短上衣short sleeve top1长上衣long sleeve top2短外套short sleeve outwear3长外套long sleeve outwear4裙子skirt5裤子trousers6连衣裙dre…

Java并发编程哲学系列汇总

文章目录 并发编程基础并发编程进阶并发编程实践 并发编程基础 Java并发编程基础小结 Java线程池知识点小结 详解JUC包下各种锁的使用 并发编程利器Java CAS原子类全解 深入理解Java中的final关键字 Java并发容器深入解析&#xff1a;HashMap与ArrayList线程安全问题及解…

git 之 stash

一、git stash&#xff1a;临时保存工作区修改 作用 将当前工作目录和暂存区的未提交修改保存到栈中&#xff0c;并恢复工作区到上一次提交的干净状态。 适用场景&#xff1a; 临时切换分支修复紧急 Bug拉取远程代码前清理工作区保存实验性代码避免生成无效提交 常用命令&am…

vxe-grid 双击行,打开expand的内容

1、官网api Vxe Table v4.6&#xff08;根据版本&#xff09; 要调用这个事件&#xff0c;双击单元格&#xff0c;我们打开type"expand"的内容 2、打开的事件toggleRowExpand 3、事件的说明 这个方法&#xff0c;会自动判断当前展开的状态&#xff0c;然后去触发相…

Java Stream 高级实战:并行流、自定义收集器与性能优化

一、并行流深度实战&#xff1a;大规模数据处理的性能突破 1.1 并行流的核心应用场景 在电商用户行为分析场景中&#xff0c;需要对百万级用户日志数据进行实时统计。例如&#xff0c;计算某时段内活跃用户数&#xff08;访问次数≥3次的用户&#xff09;&#xff0c;传统循环…

计算机系统结构-第5章-监听式协议

监听式协议******&#xff1a; 思想: 每个Cache除了包含物理存储器中块的数据拷贝之外&#xff0c;也保存着各个块的共享状态信息。 Cache通常连在共享存储器的总线上&#xff0c;当某个Cache需要访问存储器时&#xff0c;它会把请求放到总线上广播出去&#xff0c;其他各个C…

(c++)string的模拟实现

目录 1.构造函数 2.析构函数 3.扩容 1.reserve(扩容不初始化) 2.resize(扩容加初始化) 4.push_back 5.append 6. 运算符重载 1.一个字符 2.一个字符串 7 []运算符重载 8.find 1.找一个字符 2.找一个字符串 9.insert 1.插入一个字符 2.插入一个字符串 9.erase 10…

学习笔记(24): 机器学习之数据预处理Pandas和转换成张量格式[2]

学习笔记(24): 机器学习之数据预处理Pandas和转换成张量格式[2] 学习机器学习&#xff0c;需要学习如何预处理原始数据&#xff0c;这里用到pandas&#xff0c;将原始数据转换为张量格式的数据。 学习笔记(23): 机器学习之数据预处理Pandas和转换成张量格式[1]-CSDN博客 下面…

LeetCode 2297. 跳跃游戏 VIII(中等)

题目描述 给定一个长度为 n 的下标从 0 开始的整数数组 nums。初始位置为下标 0。当 i < j 时&#xff0c;你可以从下标 i 跳转到下标 j: 对于在 i < k < j 范围内的所有下标 k 有 nums[i] < nums[j] 和 nums[k] < nums[i] , 或者对于在 i < k < j 范围…

【前端】缓存相关

本知识页参考&#xff1a;https://zhuanlan.zhihu.com/p/586060532 1. 概述 1.1 应用场景 静态资源 场景&#xff1a;图片、CSS、JS 文件等静态资源实现&#xff1a;使用 HTTP 缓存控制头&#xff0c;或者利用 CDN 进行边缘缓存 数据缓存 场景&#xff1a;请求的返回结果实现…

猎板硬金镀层厚度:高频通信领域的性能分水岭

在 5G 基站、毫米波雷达等高频场景中&#xff0c;硬金镀层厚度的选择直接决定了 PCB 的信号完整性与长期可靠性。猎板硬金工艺&#xff1a; 1.8μm 金层搭配罗杰斯 4350B 基材的解决方案&#xff0c;在 10GHz 频段实现插入损耗&#xff1c;0.15dB/cm&#xff0c;较常规工艺降低…

第35次CCF计算机软件能力认证-5-木板切割

原题链接&#xff1a; TUOJ 我自己写的35分正确但严重超时的代码 #include <bits/stdc.h> using namespace std; int main() {int n, m, k;cin >> n >> m >> k;vector<unordered_map<int, int>> mp(2);int y;for (int i 1; i < n; …

【蓝桥杯】包子凑数

包子凑数 题目描述 小明几乎每天早晨都会在一家包子铺吃早餐。他发现这家包子铺有 NN 种蒸笼&#xff0c;其中第 ii 种蒸笼恰好能放 AiAi​ 个包子。每种蒸笼都有非常多笼&#xff0c;可以认为是无限笼。 每当有顾客想买 XX 个包子&#xff0c;卖包子的大叔就会迅速选出若干…

pikachu通关教程-目录遍历漏洞(../../)

目录遍历漏洞也可以叫做信息泄露漏洞、非授权文件包含漏洞等. 原理:目录遍历漏洞的原理比较简单&#xff0c;就是程序在实现上没有充分过滤用户输入的../之类的目录跳转符&#xff0c;导致恶意用户可以通过提交目录跳转来遍历服务器上的任意文件。 这里的目录跳转符可以是../…

[概率论基本概念4]什么是无偏估计

关键词&#xff1a;Unbiased Estimation 一、说明 对于无偏和有偏估计&#xff0c;需要了解其叙事背景&#xff0c;是指整体和抽样的关系&#xff0c;也就是说整体的叙事是从理论角度的&#xff0c;而估计器原理是从实践角度说事&#xff1b;为了表明概率理论&#xff08;不可…

面试题——计算机网络:HTTP和HTTPS的区别?

HTTP&#xff08;HyperText Transfer Protocol&#xff09;&#xff1a;作为互联网上应用最广泛的网络通信协议&#xff0c;HTTP是基于TCP/IP协议族的应用层协议。它采用标准的请求-响应模式进行通信&#xff0c;通过简洁的报文格式&#xff08;包含请求行、请求头、请求体等&a…