Electron 结合 Selenium + chromedriver 驱动服务实现浏览器多开
背景
在调研浏览器多开的过程中,electron 有自带的 browserview,webview,但是上面两个受制于 electron 内核版本限制,升级不够灵活,对新版的网页支持可能不及时,甚至不兼容,必须通过发布新的客户端版本才能解决,此外,这两个组件本身也不稳定,经常内存溢出,如果能改为 chrome 自己开发的浏览器内核来运行,则以上问题解决起来都不会特别吃力,所以才有了对 Electorn 控制浏览器多开的技术调研。
思路
-
在开发爬虫时,我了解导 selenium 和 chromedriver,其中 selenium 有个 node.js 调用库(还有 php,python,java 等包),其中 selenium 是一个 webdriver 协议,webdriver 是什么?和 chromedriver 有什么区别?这个后续再说。selenium 基于 webdriver 协议并且封装了 webdriver 协议,用以操控浏览器,而 chromedriver 负责桥接 selenium 和 chrome 浏览器,这样就实现了浏览器多开。
-
在研究爬虫时,还发现 puppeteer 库,这个库就比较特殊,它不依赖 chromedriver,那就意味着 puppeteer 自己实现了一套 chromedriver 用来管理 chrome,同时自己还实现了 selenium 的封装,如果将 puppeteer 打包到 electron 包中,那就要解决 chrome 执行路径的问题。
实现
-
puppeteer 这个还没跑通,这个也没有现成的案例,github 有个库,但是只支持 node.js 18,而我用的 electron 依赖 node.js 16,此外还需要 puppeteer 的版本和 electron 的版本对应,这个处理起来比较复杂,也没有人给予一个完整可运行的 demo 包,因为暂时放弃这方面的探索。
electron 官网中讲了 selenium 和 chromedriver
这是一个比较古老的文档,electron 更新频率过快,很多库都懒得跟进 electron,选择 electron 本身就是个大坑,要面对的问题很多,要求掌握的知识也很多,还解决不了这些基础的 C++问题
Selenium 和 WebDriver | Electron
webdriver vs chromedriver 的区别
WebDriver
WebDriver 是一种定义了如何通过代码来操作浏览器的接口。它是一个规范(或者说协议),由 W3C 制定,旨在通过统一的接口与各种浏览器进行交互。WebDriver 允许开发人员编写代码来控制浏览器执行各种操作,如打开网页、点击按钮、输入文本等。
ChromeDriver
ChromeDriver 是 WebDriver 的一个具体实现,它专门用于与 Google Chrome 浏览器进行交互。ChromeDriver 充当一个独立的服务,用于接收 WebDriver 的命令并将这些命令转发给 Chrome 浏览器,从而控制浏览器的行为。它是由开发 Chromium 和 WebDriver 的团队维护的。
electron 文档讲的乱乱的
-
看上面的 electron 你会很懵逼,对方讲了很多套路和方法,但由于一些东西缺失具体的演示,你根本不知道干嘛的
electron 文档核心点解析
-
开头
配置 Spectron
没啥用,你可以直接忽略,看起来这个库都被放弃了 -
紧接着 Electron 给了两种 webdriver 实现协议,一种是
WebDriverJs
,一种是WebdriverIO
,我一开始还以为这两者是顺序关系呢,其实是互斥的关系,是两种独立实现方式,第一种比较像 selenium,库名字也有 selenium,npm install selenium-webdriver
, 第二种,ChatGPT-4o 说是一种简化写法,类似于 js 和 jquery 的关系,但其实第一种就够用了。 -
其中讲到的
npm install electron-chromedriver
也是一种误导,其实就是 chromedriver,你装这个还会搞不清楚 chromedriver 和 chrome 两者之间的版本问题,但这里的 electron-chromedriver 应该是可以驱动 electron 自带的 chrome 浏览器的,但本文并不想探讨这个问题。
如何找到 chromedriver 以及对应的 chrome
开发爬虫最麻烦的点,就在于 chromedriver 和 chrome 的版本对应关系,这会让新手搔头抓耳,不过早有一批人整理了这些东西,我分享在这里
https://googlechromelabs.github.io/chrome-for-testing/latest-versions-per-milestone-with-downloads.json
非常 nice,这个 json 查看谷歌扩展是哪个?
GitHub - tulios/json-viewer: It is a Chrome extension for printing JSON and JSONP.
还有很多风格可以选择,推荐给大家,用这个查看在线 json 事半功倍
chromedriver 是可以直接启动的
下载好之后,找到路径,在地址栏输入 cmd,按回车,即可打开控制台
默认开启 9515 端口,至于启动那个 chrome,这是 selenium 那边控制的,chromedriver 会根据你给的 chrome.exe 去找到 chrome,来执行命令
我们将 119 版本的 chrome 下载下来放到 D 盘
在 Electron 主进程中编写一个启动函数
在 ready 事件中调用
function openChrome(){const webdriver = require('selenium-webdriver')const driver = new webdriver.Builder()// "9515" 是ChromeDriver使用的端口.usingServer('http://localhost:9515').withCapabilities({'goog:chromeOptions': {// 这里填您的Electron二进制文件路径。binary: "D:\\chrome-win64\\chrome.exe",args: ['--no-sandbox', '--enable-chrome-browser-cloud-management']},}).forBrowser('chrome').build()driver.get('https://www.google.com')driver.findElement(webdriver.By.name('q')).sendKeys('webdriver')driver.executeScript(`setTimeout(function() {var inputElement = document.querySelector('input[name="btnK"]');if (inputElement) {inputElement.click();} else {console.error('元素未找到');}}, 3000);`);
}
app.on('ready', openChrome)
运行脚本 npm run dev
就可以拉起浏览器了,通过给于不同的用户目录,就可以打开多个独立的浏览器同时运行,如果你将目录更换为最新用户自带的 chrome 浏览器地址也可以,不过这样
相关文章:

Electron 结合 Selenium + chromedriver 驱动服务实现浏览器多开
背景 在调研浏览器多开的过程中,electron 有自带的 browserview,webview,但是上面两个受制于 electron 内核版本限制,升级不够灵活,对新版的网页支持可能不及时,甚至不兼容,必须通过发布新的客…...

手持式气象检测设备:便携科技,气象探测
一、手持式气象检测设备:小巧身躯,大能量 手持式气象检测设备,顾名思义,是一种可以手持操作的气象监测工具。它集成了温度、湿度、气压、风速风向等多种传感器,能够实时获取气象数据,并通过显示屏或手机APP…...
shell 发送邮件脚本(免密)
#!/bin/bash ENV$1 TARGET_VERSION$2 TO$3 # SMTP服务器设置 SMTP_SERVER"邮箱服务地址" SMTP_PORT"25"# 邮件信息 FROM"jenkinsy.com" SUBJECT"Deployment Status Notification" BODY$ENV"发布完成,版本 :…...

Web动画(lottie篇)
一、Lottie简介 Lottie是一个库,可以解析使用AE制作的动画(需要用bodymovin导出为json格式),支持web、ios、android和react native。在web侧,lottie-web库可以解析导出的动画json文件,并将其以svg或者canva…...

昇思25天学习打卡营第20天|CV-ResNet50图像分类
打卡 目录 打卡 图像分类 ResNet网络介绍 数据集准备与加载 可视化部分数据集 残差网络构建 Building Block 结构 代码实现 Bottleneck结构 代码实现 构建ResNet50网络 代码定义 模型训练与评估 可视化模型预测 重点:通过网络层数加深,感知…...
grep: /etc/mysql/my.cnf: 没有那个文件或目录
当你收到 "grep: /etc/mysql/my.cnf: 没有那个文件或目录" 的错误信息时,这意味着你的系统上可能没有默认的 MySQL/MariaDB 配置文件 /etc/mysql/my.cnf。MariaDB 和 MySQL 可能会使用不同的配置文件路径。下面是一些步骤来帮助你找到正确的配置文件&…...

养猫好物|宠物空气净化器是不是智商税?靠谱猫毛空气净化器推荐
宠物空气净化器是不是智商税?宠物空气净化器是否真有其效,是许多由于要不要买空气净化器养宠人心中的疑惑。作为呼吸科医生,我深知良好空气质量对呼吸道健康的重要性,因此建议所有家庭,尤其是养有猫狗等宠物的家庭&…...

【CPS出版】2024年智能计算与数据分析国际学术会议(ICDA 2024,9月6日-8)
为探讨数据科学和计算智能领域的关键问题,促进相关交流,2024年智能计算与数据分析国际学术会议(ICDA 2024)将于2024年9月6日-8日在中国青岛召开。 本届会议拟邀请数据分析和计算智能领域的顶级专家、学者和产业界优秀人才,围绕当前…...

AutoGen框架革新:解锁新闻稿写作的新境界
前言 今天带来的仍然是AutoGen基于AssistantAgent和UserProxyAgent的例子,以帮助大家一起消化目前最前卫的AI应用框架。这是一个AIGC最擅长,因为生成新闻稿嘛,同时又需要利用Agent的一个常规Demo。了解LangChain的同学,会通过对比…...

数据结构之队列详解
1.队列的概念以及结构 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFo(Frist in Frist out)的特性 入队列:进行插入才操作的一端称为队尾 出队列:进行删除操作的一…...

[渗透测试] 反序列化漏洞
反序列化漏洞 序列化:将对象的状态信息转换为可以传输或存储的形式的过程。简单的来说,就是将一个抽象的对象转换成可以传输的字符串 ,以特定的形式在进行之间实现跨平台的传输。 序列化大多以字节流、字符串、json串的形式来传输。将对…...
C++ 类型转换 包括C风格的转换、static_cast、const_cast、reinterpret_cast、dynamic_cast、模板特化等
C 类型转换 包括C风格的转换、static_cast、const_cast、reinterpret_cast、dynamic_cast、模板特化等 flyfish 0. 隐式转换(Implicit Conversions) 隐式转换是编译器自动进行的类型转换,通常在需要将一个类型转换为另一个类型以匹配函数参…...
等保通过标准
等保测评,即信息系统安全等级保护测评,是国家对信息系统安全等级保护的一种评估活动。它涉及到安全管理、安全技术、安全运维等多个方面,旨在评定信息系统是否达到了国家设定的安全等级保护标准。等保测评的通过标准通常会根据信息系统的安全…...
reduceByKey 函数详解
reduceByKey 函数详解 实现原理 reduceByKey 函数主要用于处理分布式数据集。它接收两个操作符作为参数: keySelector:这是一个映射函数,用于从输入元素中提取键。 valueReducer:这是另一个函数,用于将具有相同键的…...

CSI-RS在信道中传输的过程
简单介绍CSI-RS信号生成,在信道中传输和接收的过程 1.载波配置 首先需要配置载波相关的参数 系统带宽和子载波间隔 5G NR中,系统带宽和子载波间隔是两个关键参数,共同决定无线资源的分配和使用 系统带宽 5G NR支持广泛的系统带宽&…...
建造者模式(Builder Pattern)工作原理
文章目录 [toc]建造者模式(Builder Pattern)工作原理一、基本概念二、主要角色三、工作流程(一)定义产品(二)定义抽象建造者(三)定义具体建造者(四)定义指挥者…...
Ubuntu22.04安装Go语言的几种方式
在 Ubuntu 22.04 上安装 Go 语言可以通过几种不同的方法,以下是两种常见的安装方法: 方法1:使用 go 官方安装脚本 打开终端。 下载 Go 语言的安装脚本: curl -O https://go.dev/dl/go1.22.5.linux-amd64.tar.gz请检查 Go 官方网…...

Typora笔记上传到CSDN
1.Typora 安装 Typora链接:百度网盘 提取码:b6d1 旧版本是不需要破解的 后来的版本比如1.5.9把放在typora的根目录下就可以了 2.上传到CSDN 步骤 csdn 写文章-使用MD编辑器-导入本地md文件即可 问题 图片没法显示 原因 图片的链接是本地的 当然没法…...

Modbus转BACnet/IP网关BA100-配硬件说明
在现代自动化系统中,不同设备和系统之间的通信至关重要,Modbus和BACnet/IP协议虽然各有优势,但它们之间的直接通信存在障碍。钡铼Modbus转BACnet/IP网关作为连接这两种协议的桥梁,允许不同系统之间的无缝数据交换。 一、Modbus转…...

DjangoRF实战-2-apps-users
1、用户模块 创建一个用户模块子应用,用来管理用户,和认证和授权。 1.1根目录创建apps, 为了使用方便,还需要再pycharm中设置一下资源路径,就可以自动提示 1.2注册子应用 1.3添加应用根目录到环境变量path python导…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...