当前位置: 首页 > news >正文

网络爬虫学习:应用selenium获取Edge浏览器版本号,自动下载对应版本msedgedriver,确保Edge浏览器顺利打开。

一、前言

我从24年11月份开始学习网络爬虫应用开发,经过2个来月的努力,于1月下旬完成了开发一款网络爬虫软件的学习目标。这里对本次学习及应用开发进行一下回顾总结。

前几天我已经发了一篇日志(网络爬虫学习:应用selenium从搜*狐搜索爬取新闻结果的数据)记录了应用中使用的爬虫技术。

这篇日志记录另外一个问题的解决。

二、问题描述

我在完成软件的初步开发后,曾将软件打包成exe文件后,拷贝到两位同事的电脑上进行检测,软件可以正常打开,但是在输入关键字,点击搜索按钮后,Edge浏览器却一直没有弹出。之后通过研究和对比,找出了原因。

我安装的selenium 库版本号是4.27.1,这个版本的selenium在执行 webdriver.Edge() 方法时,如果没有指定“msedgedriver.exe”,会自动下载msedgedriver.exe文件并保存到C盘  > 用户 > 用户名(如Administer、Lenovo等) > .cache > selenium > msedgedriver > win64 > 驱动版本号 文件夹下。且下载的msedgedriver文件的版本号能够兼容用户电脑上的Edge浏览器。

(selenium自动下载的msedgedriver.exe)

回忆我学习selenium 库的时候,好像刚开始也出现过隔了好一会才打开Edge浏览器的情况。并且在研究如何解决问题的过程中,我曾打开Edge浏览器检查版本号,发现浏览器在更新,并且在浏览器更新后我在进入pycharm调试我开发的软件时,同样出现了打开Edge浏览器等待时间长的情况,基本可以判断造成长时间不打开Edge浏览器的原因是软件正在下载msedgedriver.exe,由于我公司的内部网络有限速,导致下载时间长。

找到原因后,我一开始尝试的方法是:下载好与使用者电脑Edge浏览器版本号一致的msedgedriver.exe,并copy到使用者电脑C盘的 “.cache” 目录中对应的子文件夹下。再次运行我开发的爬虫软件,这次可以较快速的打开Edge浏览器了。

不过这种手动添加的方法,很不方便,不太可取。首先是,我的同事大多不精通电脑,这个操作对他们来说有难度。而如果都由我一个个的设置,则比较麻烦。其次,我发现我开发的电脑与软件测试的2台电脑中的Edge浏览器版本号都不一样,且我的电脑Edge用得比较多,版本都升级了好几次了, “.cache” 目录内已经下载了好几个版本的msedgedriver.exe了。查询 Microsoft Edge Driver官网 可以看到msedgedriver的版本号非常多,在无法确定使用者电脑中Edge浏览器的版本号时,难道要把这些版本的驱动都下载?那也太麻烦了,且占用的存储空间也很大。

否定了手动添加msedgedriver.exe的方法后,就需要寻找更有效的方法让使用者可以方便的下载和配置msedgedriver.exe了。

三、借助DeepSeek获取解决办法

正好这几天DeepSeek上了热搜,看到相关的文章,让我对DeepSeek产生了兴趣,就尝试了用DeepSeek来解决问题,结果从DeepSeek给的答案中找到了解决问题的方法。

我一共向DeepSeek提了2个问题。

第1问:“使用selenium库,如何获取edge浏览器的版本号”。

这一问的目的是希望通过自己开发的应用获取到Edge浏览器的版本号,为下一步下载对应版本的msedgedriver.exe做准备。DeepSeek思考了64秒,给了我一份详细的答案。在这份答案中给出了“通过driver.capabilities获取浏览器的详细信息”的方法。

这个方法也确实可以获取到Edge浏览器的版本号,不过此法仍需通过webdriver.Edge() 方法打开Edge浏览器,才能获取到浏览器的版本信息(同时还能获取到msedgedriver.exe的版本号信息),但我之前遇到的问题是在使用者的电脑上并没有下载和配置好msedgedriver.exe,导致了打开Edge浏览器需要很长的时间,而我又暂时无法在软件中给出足够有效的提示,因此,这个办法不适合我遇到的问题。

(第1问)

(第1问的答案)

接着我又提出了第2问:“使用python进行爬虫软件开发,如果没有提前下载msedgedriver驱动,在软件中执行webdriver.Edge()方法,无法打开Edge浏览器,如何处理。”

这一问的描述更详尽一些,且是接着上一问提的,DeepSeek这次比较给力,只思考了34秒,最终给了我三个解决方法,从中,我选择了第二个方法。另外两个方法我并未尝试。

(第1问)

(第2问给的第一个方法)

(第2问给的第二个方法)

(第2问给的第三个方法)

四、功能实现

我基于DeepSeek给的方案完善了自己的爬虫软件,在应用中,添加了检查浏览器版本号和msedgedriver.exe的版本号的功能,一旦发现版本号不一致,或信息缺失,就会提示用户下载msedgedriver.exe。软件会将msedgedriver.exe下载到应用工作目录的drivers文件夹下。另外,我在所有调用webdriver.Edge() 方法的代码块,都添加了指定msedgedriver.exe文件路径的语句,使webdriver.Edge() 方法可以直接到指定目录下找到msedgedriver.exe,这样就可以加快Edge浏览器的启动了。解决问题的代码分以下几个部分(具体代码见“五、代码展示”):

1. get_edge_version()方法:

从注册表中获取Edge浏览器的版本号

2. get_edgedriver_version()方法:

获取msedgedriver的版本号

3. download_edgedriver()方法:

下载Edge浏览器对应版本的msedgedriver

4. check_system_bit()方法:

检查操作系统是64位还是32位,根据此方法结果决定下载win64还是win32的msedgedriver

5. vrsion_comparison()方法:

比较浏览器和驱动的版本号

6. open_edge()方法:

用于展示执行webdriver.Edge方法时检查和设置msedgedriver

五、代码展示

最后放上功能实现的示例代码供参考,可以直接运行。

from selenium import webdriver
from selenium.webdriver.edge.service import Service
import time
import re
import winreg  # Windows系统 用于从注册表中获取信息
import requests
import zipfile
import os
import subprocess  # 用于获取驱动器的版本号def get_edge_version():""" 从注册表中获取Edge浏览器的版本号 """try:key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Edge\BLBeacon")version, _ = winreg.QueryValueEx(key, "version")winreg.CloseKey(key)return versionexcept Exception:return Nonedef get_edgedriver_version():""" 获取Edge驱动器版本号 """# 指定msedgedriver的路径msedgedriver_path = os.path.abspath("drivers/msedgedriver.exe")try:# 尝试获取版本信息ver = subprocess.run([msedgedriver_path, '--version'], capture_output=True, text=True)if ver.returncode == 0:# 形如:Microsoft Edge WebDriver 120.0.2210.91 (f469d579f138ffc82b54354de66117c1cb1bb923)match = re.search(r'(\d+\.\d+\.\d+\.\d+)', ver.stdout.strip())if match:vrsion = match.group(1)return vrsionelse:return Noneelse:print("获取版本时出错:", ver.stderr.strip())return Noneexcept Exception as e:print("出现错误:", str(e))return Nonedef download_edgedriver(version: str):""" 下载对应版本的msedgedriver """# 检查操作系统位数architecture = check_system_bit()if architecture == 64:# 下载win64位的压缩包url = f'https://msedgedriver.azureedge.net/{version}/edgedriver_win64.zip'else:# 下载win32位的压缩包url = f'https://msedgedriver.azureedge.net/{version}/edgedriver_win32.zip'print('驱动器压缩包下载地址:')print(url)response = requests.get(url)print('开始获取驱动器压缩包')# 保存并解压驱动zip_path = f"edgedriver_win{architecture}.zip"with open(zip_path, 'wb') as f:f.write(response.content)print(f'驱动器压缩包已下载到当前工作目录内,文件名{zip_path}')with zipfile.ZipFile(zip_path, 'r') as zip_ref:zip_ref.extractall("drivers/")os.remove(zip_path)print('文件已解压,压缩包已删除')return os.path.abspath("drivers/msedgedriver.exe")def check_system_bit():""" 检查操作系统位数 """if 'PROGRAMFILES(X86)' in os.environ:print("你的电脑为 64-bit 操作系统")return 64else:print("你的电脑为 32-bit 操作系统")return 32def vrsion_comparison(edge_v: str, driver_v: str):""" 比较浏览器和驱动的版本号 """if edge_v == driver_v:return Trueelse:return Falsedef open_edge(url):""" 用于展示执行webdriver.Edge方法时检查和设置msedgedriver """# 获取浏览器版本edge_version = get_edge_version()# 获取驱动器版本,同时也是检查驱动器是否存在driver_version = get_edgedriver_version()if edge_version and driver_version:math = vrsion_comparison(edge_version, driver_version)if not math:print('浏览器和驱动器版本号不一致,但我们仍尝试打开浏览器')try:# 指定msedgedriver.exe的完整路径path_to_executable = os.path.abspath("drivers/msedgedriver.exe")service = Service(executable_path=path_to_executable)driver = webdriver.Edge(service=service)driver.get(url)# 等待页面加载完成time.sleep(30)except Exception as e:print(f'打开驱动器出错:{e}')else:print('浏览器或驱动器版本信息缺失,可能导致异常,故暂不能执行爬虫任务。')if __name__ == '__main__':# 1.获取edge浏览器版本号edge_version = get_edge_version()print("Edge浏览器版本号:", edge_version)# 2.获取驱动器版本driver_version = get_edgedriver_version()print("msedgedriver版本号:", driver_version)# 3.进行版本信息检查check_ok = Falseif driver_version:if edge_version:# 比较浏览器和驱动器的版本号result = vrsion_comparison(edge_version, driver_version)if result:print('浏览器和驱动的版本一致')check_ok = Trueelse:print(f'浏览器版本{edge_version} 和 驱动器版本{driver_version} 不一致')select = input('是否下载浏览器对应版本的驱动?(Y/N)?').strip()select = select.lower()if select == 'y':# 4.下载驱动器print('开始下载浏览器驱动,请稍候')driver_path = download_edgedriver(edge_version)print(f'驱动已下载,保存在 {driver_path}')check_ok = Trueelse:print('您未下载浏览器对应版本的驱动,可能会导致在软件中打开Edge浏览器出问题')else:print('未获取到Edge浏览器的版本信息')else:print('未获取到驱动版本信息')select = input('是否下载浏览器对应版本的驱动?(Y/N)?').strip()select = select.lower()if select == 'y':# 4.下载驱动器print('开始下载浏览器驱动,请稍候')driver_path = download_edgedriver(edge_version)print(f'驱动已下载,保存在 {driver_path}')check_ok = Trueelse:print('您未下载浏览器对应版本的驱动,可能会导致在软件中打开Edge浏览器出问题')# 4. 打开浏览器if check_ok:m_url = 'https://www.baidu.com/'open_edge(m_url)

相关文章:

网络爬虫学习:应用selenium获取Edge浏览器版本号,自动下载对应版本msedgedriver,确保Edge浏览器顺利打开。

一、前言 我从24年11月份开始学习网络爬虫应用开发,经过2个来月的努力,于1月下旬完成了开发一款网络爬虫软件的学习目标。这里对本次学习及应用开发进行一下回顾总结。 前几天我已经发了一篇日志(网络爬虫学习:应用selenium从搜…...

【go语言】结构体

一、type 关键字的用法 在 go 语言中,type 关键字用于定义新的类型,他可以用来定义基础类型、结构体类型、接口类型、函数类型等。通过 type 关键字,我们可以为现有类型创建新的类型别名或者自定义新的类型。 1.1 类型别名 使用 type 可以为…...

Spring Boot是什么及其优点

简介 Spring Boot是基于Spring框架开发的全新框架,其设计目的是简化Spring应用的初始化搭建和开发过程。 Spring Boot整合了许多框架和第三方库配置,几乎可以达到“开箱即用”。 优点 可快速构建独立的Spring应用。 直接嵌入Tomcat、Jetty和Underto…...

谷氨酸:大脑功能的多面手

标题:谷氨酸:大脑功能的多面手 文章信息摘要: 谷氨酸是大脑中最主要的兴奋性神经递质,参与了90%以上的神经元激活,在蛋白质合成、味觉(鲜味)以及神经可塑性中发挥重要作用。它与GABA、多巴胺等…...

SpringCloudGateWay和Sentinel结合做黑白名单来源控制

假设我们的分布式项目,admin是8087,gateway是8088,consumer是8086 我们一般的思路是我们的请求必须经过我们的网关8088然后网关转发到我们的分布式项目,那我要是没有处理我们绕过网关直接访问项目8087和8086不也是可以&#xff1…...

HTML新春烟花

系列文章 序号目录1HTML满屏跳动的爱心(可写字)2HTML五彩缤纷的爱心3HTML满屏漂浮爱心4HTML情人节快乐5HTML蓝色爱心射线6HTML跳动的爱心(简易版)7HTML粒子爱心8HTML蓝色动态爱心9HTML跳动的爱心(双心版)10…...

【Elasticsearch】中数据流需要配置索引模板吗?

是的,数据流需要配置索引模板。在Elasticsearch中,数据流(Data Streams)是一种用于处理时间序列数据的高级结构,它背后由多个隐藏的索引组成,这些索引被称为后备索引(Backing Indices&#xff0…...

Git进阶之旅:Git 配置信息 Config

Git 配置级别: 仓库级别:local [ 优先级最高 ]用户级别:global [ 优先级次之 ]系统级别:system [ 优先级最低 ] 配置文件位置: git 仓库级别对应的配置文件是当前仓库下的 .git/configgit 用户级别对应的配置文件时用…...

buu-pwn1_sctf_2016-好久不见29

这个也是栈溢出,不一样的点是,有replace替换,要输入0x3c字符(60),Iyou 所以,20个I就行,找后面函数 输出提示信息,要求用户输入关于自己的信息。 使用fgets函数从标准输入…...

ES2021+新特性、常用函数

一、ES2021新特性 ES2021 数字分隔符 let num 1234567 let num2 1_234_567 Promise.any 与 Promise.all 类似,Promise.any 也接受一个 Promise 的数组。当其中任何一个 Promise 完成(fullfill)时,就返回那个已经有完成值的 …...

STM32——LCD

一、引脚配置 查看引脚 将上述引脚都设置为GPIO_Output 二、导入驱动文件 将 LCD 驱动的 Inc 以及 Src 中的 fonts.h,lcd.h 和 lcd.c 导入到自己工程的驱动文件中。 当然,后面 lcd 的驱动学习可以和 IMX6U 一块学。 三、LCD函数 void LCD_Clear(u16 Color); 功能…...

【redis进阶】分布式锁

目录 一、什么是分布式锁 二、分布式锁的基础实现 三、引入过期时间 四、引入校验 id 五、引入lua 六、引入 watch dog (看门狗) 七、引入 Redlock 算法 八、其他功能 redis学习🥳 一、什么是分布式锁 在一个分布式的系统中,也会涉及到多个节点访问同一…...

园区管理系统如何提升企业核心竞争力与资产管理智能化水平

内容概要 在当今快节奏的商业环境中,园区管理系统正成为企业的重要合作伙伴,尤其在工业园、产业园、物流园、写字楼和公寓等多种类型的物业管理中。这个系统不仅仅是一个管理工具,它还是提升企业运营效率和核心竞争力的关键因素。通过智能化…...

AI大模型开发原理篇-3:词向量和词嵌入

简介 词向量是用于表示单词意义的向量, 并且还可以被认为是单词的特征向量或表示。 将单词映射到实向量的技术称为词嵌入。在实际应用中,词向量和词嵌入这两个重要的NLP术语通常可以互换使用。它们都表示将词汇表中的单词映射到固定大小的连续向量空间中…...

高精度算法:高精度减法

P2142 高精度减法 - 洛谷 | 计算机科学教育新生态 我们两个整数一定要是大数减去小数,所以这个点我们需要特判一下,那我们两个字符串表示的整型怎么判断大小呢,我们字典序比较大小和真实的数字比较大小是一样的,比如我们的‘21’…...

Java创建项目准备工作

新建项目 新建空项目 每一个空项目创建好后都要检查jdk版本 检查SDK和语言级别——Apply——OK 检查当前项目的Maven路径,如果已经配置好全局,就是正确路径不用管 修改项目字符集编码,将所有编码都调整为UTF-8 创建Spingboot工程 创建Spring…...

基于STM32的智能宠物喂食器设计

目录 引言系统设计 硬件设计软件设计 系统功能模块 定时喂食模块远程控制与视频监控模块食物存量检测与报警模块语音互动与用户交互模块数据记录与智能分析模块 控制算法 定时与手动投喂算法食物存量检测与低存量提醒算法数据记录与远程反馈算法 代码实现 喂食控制代码存量检测…...

在线课堂小程序设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...

为AI聊天工具添加一个知识系统 之77 详细设计之18 正则表达式 之5

本文要点 昨天讨论了 本项目(AI聊天工具添加一个知识系统)中正则表达式模板的设计中可能要考虑到的一些问题(讨论到的内容比较随意,暂时无法确定 那些考虑 是否 应该是正则表达式模板设计要考虑的以及 是否完整)。今天…...

【Elasticsearch】 索引模板 ignore_missing_component_templates

解释 ignore_missing_component_templates 配置 在Elasticsearch中,ignore_missing_component_templates 是一个配置选项,用于处理索引模板中引用的组件模板可能不存在的情况。当您创建一个索引模板时,可以指定一个或多个组件模板&#xff0…...

Github 2025-01-29 C开源项目日报 Top10

根据Github Trendings的统计,今日(2025-01-29统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量C项目10C++项目1Assembly项目1Go项目1我的电视 - 安卓电视直播软件 创建周期:40 天开发语言:CStar数量:649 个Fork数量:124 次关注人数:64…...

文件上传2

BUUCTF 你传你🐎呢 先上传.htaccess 修改格式 即可上传成功 返回上传图片格式的木马 用蚁剑连接 5ecf1cca-59a1-408b-b616-090edf124db5.node5.buuoj.cn:81/upload/7d8511a847edeacb5385299396a96d91/rao.jpg 即可得到flag [GXYCTF2019]BabyUpload...

Unity敌人逻辑笔记

写ai逻辑基本上都需要状态机。因为懒得手搓状态机,所以选择直接用动画状态机当逻辑状态机用。 架构设计 因为敌人的根节点已经有一个animator控制动画,只能增加一个子节点AI,给它加一个animator指向逻辑“动画”状态机。还有一个脚本&#…...

高级编码参数

1.跳帧机制 参考资料:frameskipping-hotedgevideo 跳帧机制用于优化视频质量和编码效率。它通过选择性地跳过某些帧并使用参考帧来预测和重建视频内容,从而减少编码所需的比特率,同时保持较高的视频质量。在视频编码过程中,如果…...

DeepSeek-R1:通过强化学习激励大型语言模型(LLMs)的推理能力

摘要 我们推出了第一代推理模型:DeepSeek-R1-Zero和DeepSeek-R1。DeepSeek-R1-Zero是一个未经监督微调(SFT)作为初步步骤,而是通过大规模强化学习(RL)训练的模型,展现出卓越的推理能力。通过强…...

leetcode——合并K个有序链表(java)

给你一个链表数组,每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中,返回合并后的链表。 示例 1: 输入:lists [[1,4,5],[1,3,4],[2,6]] 输出:[1,1,2,3,4,4,5,6] 解释:链表数组如下&#…...

【Valgrind】安装报错: 报错有未满足的依赖关系: libc6,libc6-dbg

Valgrind 内存泄漏检测工具安装 安装 sudo apt install valgrind官方上也是如此 但是在我的系统&#xff08;debian12)上却失败了&#xff1a; 报错有未满足的依赖关系&#xff1a; libc6 : 破坏: valgrind (< 1:3.19.0-1~) 但是 1:3.16.1-1 正要被安装 libc6-dbg : 依赖…...

vue3和vue2的区别有哪些差异点

Vue3 vs Vue2 主要差异对比指南 官网 1. 核心架构差异 1.1 响应式系统 Vue2&#xff1a;使用 Object.defineProperty 实现响应式 // Vue2 响应式实现 Object.defineProperty(obj, key, {get() {// 依赖收集return value},set(newValue) {// 触发更新value newValue} })Vue3…...

论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(六)(完结)

Understanding Diffusion Models: A Unified Perspective&#xff08;六&#xff09;&#xff08;完结&#xff09; 文章概括指导&#xff08;Guidance&#xff09;分类器指导无分类器引导&#xff08;Classifier-Free Guidance&#xff09; 总结 文章概括 引用&#xff1a; …...

NPM 使用介绍

NPM 使用介绍 引言 NPM(Node Package Manager)是Node.js生态系统中的一个核心工具,用于管理JavaScript项目的依赖包。无论是开发一个小型脚本还是构建大型应用程序,NPM都能极大地提高开发效率。本文将详细介绍NPM的使用方法,包括安装、配置、依赖管理、包发布等,帮助您…...