网络爬虫学习:应用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 version
    except Exception:
        return None


def 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 vrsion
            else:
                return None
        else:
            print("获取版本时出错:", ver.stderr.strip())
            return None
    except Exception as e:
        print("出现错误:", str(e))
        return None


def 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 64
    else:
        print("你的电脑为 32-bit 操作系统")
        return 32


def vrsion_comparison(edge_v: str, driver_v: str):
    """ 比较浏览器和驱动的版本号 """
    if edge_v == driver_v:
        return True
    else:
        return False


def 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 = False
    if driver_version:
        if edge_version:
            # 比较浏览器和驱动器的版本号
            result = vrsion_comparison(edge_version, driver_version)
            if result:
                print('浏览器和驱动的版本一致')
                check_ok = True
            else:
                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 = True
                else:
                    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 = True
        else:
            print('您未下载浏览器对应版本的驱动,可能会导致在软件中打开Edge浏览器出问题')

    # 4. 打开浏览器
    if check_ok:
        m_url = 'https://www.baidu.com/'
        open_edge(m_url)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python学opencv|读取图像(四十九)原理探究:使用cv2.bitwise()系列函数实现图像按位运算

【0】基础定义 按位与运算:两个等长度二进制数上下对齐,全1取1,其余取0。 按位或运算:两个等长度二进制数上下对齐,有1取1,其余取0。 按位异或运算: 两个等长度二进制数上下对齐,相…

U盘打开提示格式化:深度解析与数据恢复全攻略

在数字化时代,U盘作为便捷的数据存储和传输工具,广泛应用于各个领域。然而,当我们满怀期待地插入U盘,却遭遇“U盘打开提示格式化”的尴尬局面时,那份焦虑与无助感油然而生。本文将全面剖析U盘打开提示格式化的原因、应…

将5分钟安装Thingsboard 脚本升级到 3.9

稍微花了一点时间,将5分钟安装Thingsboard 脚本升级到最新版本 3.9。 [rootlab5 work]# cat one-thingsboard.shell echo "test on RHEL 8.10 " source /work/java/install-java.shell source /work/thingsboard/thingsboard-rpm.shell source /work/po…

【新春不断更】题海拾贝:P1878 舞蹈课

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》 欢迎点赞&#xff0c;关注&#xff01; 1、题…

Windows 程序设计6:错误码的查看

文章目录 前言一、说明二、使用GetLastError找到错误的原因三、使用错误码的宏总结 前言 Windows 程序设计6&#xff1a;错误码的查看。 一、说明 有时写的代码单纯看是没有问题的&#xff0c;但是执行起来就会崩溃。因此要养成判断函数执行是否成功的习惯&#xff0c;除非这…

[STM32 - 野火] - - - 固件库学习笔记 - - -十三.高级定时器

一、高级定时器简介 高级定时器的简介在前面一章已经介绍过&#xff0c;可以点击下面链接了解&#xff0c;在这里进行一些补充。 [STM32 - 野火] - - - 固件库学习笔记 - - -十二.基本定时器 1.1 功能简介 1、高级定时器可以向上/向下/两边计数&#xff0c;还独有一个重复计…

安装zsh并美化

0 Zsh 是一种功能强大的 shell&#xff0c;通常用于替代默认的 Bash shell。它为命令行提供了更多的功能&#xff0c;例如自动补全、强大的模式匹配和主题支持等。 Oh My Zsh 是用于管理 Zsh 配置的框架。 powerlevel10k是样式&#xff0c;通过p10k configure脚本可以调节自己…

Hive:复杂数据类型之Map函数

Map函数 是Hive里面的一种复杂数据类型, 用于存储键值对集合。Map中的键和值可以是基础类型或复合类型&#xff0c;这使得Map在处理需要关联存储信息的数据时非常有用。 定义map时,需声明2个属性: key 和 value , map中是 key value 组成一个元素 key-value, key必须为原始类…

WPF基础 | 深入 WPF 事件机制:路由事件与自定义事件处理

WPF基础 | 深入 WPF 事件机制&#xff1a;路由事件与自定义事件处理 一、前言二、WPF 事件基础概念2.1 事件的定义与本质2.2 常见的 WPF 事件类型 三、路由事件3.1 路由事件的概念与原理3.2 路由事件的三个阶段3.3 路由事件的标识与注册3.4 常见的路由事件示例 四、自定义事件处…

Sklearn 中的逻辑回归

逻辑回归的数学模型 基本模型 逻辑回归主要用于处理二分类问题。二分类问题对于模型的输出包含 0 和 1&#xff0c;是一个不连续的值。分类问题的结果一般不能由线性函数求出。这里就需要一个特别的函数来求解&#xff0c;这里引入一个新的函数 Sigmoid 函数&#xff0c;也成…

【Rust自学】14.6. 安装二进制crate

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 14.6.1. 从cratea.io安装二进制crate 通过cargo_install命令可以从crates.io安装二进制crate。 这并不是为了替换系统包&#xff0c;它应…

Vue 组件开发:构建高效可复用的前端界面要素

1 引言 在现代 Web 开发中,构建高效且可复用的前端界面要素是提升开发效率和用户体验的关键。Vue.js 作为一种轻量级且功能强大的前端框架,提供了丰富的工具和机制,帮助开发者快速构建高质量的应用程序。通过合理设计和封装 Vue 组件,我们可以实现组件的高效复用,提高开发…

Qt Ribbon使用实例

采用SARibbon创建简单的ribbon界面 实例代码如下所示&#xff1a; 1、头文件&#xff1a; #pragma once #include <SARibbonBar.h> #include "SARibbonMainWindow.h" class QTextEdit; class SAProjectDemo1 : public SARibbonMainWindow { Q_OBJECT pub…

微服务入门(go)

微服务入门&#xff08;go&#xff09; 和单体服务对比&#xff1a;里面的服务仅仅用于某个特定的业务 一、领域驱动设计&#xff08;DDD&#xff09; 基本概念 领域和子域 领域&#xff1a;有范围的界限&#xff08;边界&#xff09; 子域&#xff1a;划分的小范围 核心域…

【Unity3D】实现2D角色/怪物死亡消散粒子效果

核心&#xff1a;这是一个Unity粒子系统自带的一种功能&#xff0c;可将粒子生成控制在一个Texture图片网格范围内&#xff0c;并且粒子颜色会自动采样图片的像素点颜色&#xff0c;之后则是粒子编辑出消散效果。 Particle System1物体&#xff08;爆发式随机速度扩散10000个粒…

AAAI2024论文解读|HGPROMPT Bridging Homogeneous and Heterogeneous Graphs

论文标题 HGPROMPT: Bridging Homogeneous and Heterogeneous Graphs for Few-shot Prompt Learning 跨同构异构图的小样本提示学习 论文链接 HGPROMPT: Bridging Homogeneous and Heterogeneous Graphs for Few-shot Prompt Learning论文下载 论文作者 Xingtong Yu, Yuan…

密码学的数学基础1-整数 素数 和 RSA加密

数学公式推导是密码学的基础, 故开一个新的课题 – 密码学的数学基础系列 素数 / 质数 质数又称素数。 一个大于1的自然数&#xff0c;除了1和它自身外&#xff0c;不能被其他自然数整除的数叫做质数&#xff1b;否则称为合数&#xff08;规定1既不是质数也不是合数&#xff0…

使用CSS实现一个加载的进度条

文章目录 使用CSS实现一个加载的进度条一、引言二、步骤一&#xff1a;HTML结构与CSS基础样式1、HTML结构2、CSS基础样式 三、步骤二&#xff1a;添加动画效果1、使用CSS动画2、结合JavaScript控制动画 四、使用示例五、总结 使用CSS实现一个加载的进度条 一、引言 在现代网页…

Oracle 创建用户和表空间

Oracle 创建用户和表空间 使用sys 账户登录 建立临时表空间 --建立临时表空间 CREATE TEMPORARY TABLESPACE TEMP_POS --创建名为TEMP_POS的临时表空间 TEMPFILE /oracle/oradata/POS/TEMP_POS.DBF -- 临时文件 SIZE 50M -- 其初始大小为50M AUTOEXTEND ON -- 支持…

图漾相机——C++语言属性设置

文章目录 前言1.SDK API功能介绍1.1 Device组件下的API测试1.1.1 相机工作模式设置&#xff08;TY_TRIGGER_PARAM_EX&#xff09;1.1.2 TY_INT_FRAME_PER_TRIGGER1.1.3 TY_INT_PACKET_DELAY1.1.4 TY_INT_PACKET_SIZE1.1.5 TY_BOOL_GVSP_RESEND1.1.6 TY_BOOL_TRIGGER_OUT_IO1.1.…