CDP和Chrome

CDP和Chrome

CDP和WebDriver Protocol

WebDriverChrome DevTools Protocol(CDP) 是用于自动化浏览器的两个主要协议,大多数的浏览器自动化工具都是基于上述其中之一来实现的。可以通过这两种形式来和浏览器交互,通过代码来控制浏览器,完成浏览器的自动化行为(包括网页加载,爬虫,截图,导出pdf等)。

WebDriver Protocol

官网地址:链接

WebDriver 是一个用于控制浏览器的远程控制接口,由 Selenium HQ 开发,后来由 W3C 标准化。它提供了一个平台和语言中立的接口,支持几乎所有主流浏览器,如 Chrome、 Firefox、 Safari、 Edge、 Opera 等。

它和浏览器的通信是通过 JSON Wire 协议完成的,提供了RESTful的web服务,这个服务端就被称为服务端(也被称为webdriver),例如chromeDriver、geckoDriver等。

有服务端就有客户端,客户端可以选择任何语言,客户端和服务端交互,服务端和浏览器交互,从而操作浏览器。常见的客户端就是selenium,nightwatch,webdriverio
在这里插入图片描述

加上我们的自己写的自动化测试代码之后,交互流程如下:

在这里插入图片描述

Chrome DevTools Protocol

官网地址:链接

ChromeDevTools Protocol (CDP)是一个基于 Chromium 的浏览器的调试协议,如 Chrome、 Edge、 Opera 等。通过它可以直接和浏览器交互。控制浏览器的行为。

客户端和浏览器之间没有类似于WebDriver Protocol的服务端(webdriver),而是客户端通过WebSocket直接和浏览器连

类似网络驱动服务器(浏览器驱动程序)的中间人。相反,浏览器是由客户端使用 CDP 直接控制的。与浏览器的通信是通过套接字连接完成的,因此也支持双向通信。客户端通过WebSocket发送命令给浏览器,浏览器执行并返回响应。

在这里插入图片描述

两个相当流行的工具是PuppeteerPlaywright。它们不依赖于webdriver,而是通过 Chrome DevTools Protocol (CDP)直接与浏览器通话。从而更加灵活稳定的控制浏览器。

区别

从代码层面来看,使用的代码接近底层,接近浏览器,代码就会变得更加的稳定和强大,但对于跨浏览器的支持会变得更少。另一方面,代码和浏览器的之间的抽象程度越高,支持的浏览器就越多,但代码会变得不稳定并且功能受限。

对比上面两种

  • WebDriver Protocol

    支持的浏览器多,但不是很稳定,并且功能不强大。

  • Chrome DevTools Protocol

    支持的浏览器少(只是相对WebDriver来说,Chrome能支持就能用),功能强大,稳定。

Webdriver ProtocolChrome DevTools Protocol
Developed by: W3CDeveloped by: Chrome Developer Tools
需要webdriver不需要webdriver
相对较慢并且不是很稳定速度快,较稳定
支持的浏览器多支持部分浏览器
无法通过提供的api来访问浏览器中网络相关的信息可以通过api来访问网络相关的信息
它的实现有:Selenium WebDriver 3, WebdriverIO, Nightwatch它的实现有:Playwright, Puppeteer, Selenium Webdriver 4, Cypress v7

不同的WebDriver有不同的实现方式,chromeDriver内部是通过DevTools protoco来控制浏览器的。

如何选择

如果跨浏览器很重要,就选webDriver,否则选择CDP

puppeteer

链接:官网,github,github-examples

Puppeteer 是 Chrome 开发团队在 2017 年发布的一个 Node.js 包,是它提供了一个高级 API,通过 DevTools 协议控制 Chrome/Chromium。

为什么选择它?

两个理由

  1. github中star数多
  2. Chrome开发团队

可以做什么?

简单来说,浏览器能做的,它都能做

  • 截图和生成PDF
  • 爬取 SPA 或 SSR 网站
  • UI 自动化测试

版本说明

从v1.7.0 版本以来,每次发布都会发布两个软件包:

  • puppeteer

    它会自动下载一个最新版本的 Chrome 用于测试(macOS 约 170MB,Linux 约 282MB,Windows 约 280MB)以及一个 chrome-headless-shell 二进制文件(从 Puppeteer v21.6.0 开始),这个二进制文件保证可以与 Puppeteer 配合正常工作。默认情况下,浏览器会下载到 $HOME/.cache/puppeteer 文件夹中(从 Puppeteer v19.0.0 开始)。

    通过puppeteer-core 控制它下载的浏览器

  • puppeteer-core

    puppeteer-core 是一个库,用于帮助驱动任何支持 DevTools 协议的内容。

    它不会下载浏览器,它提供了封装好的API和浏览器交互。

    如果自己已经下载了浏览器,就可以使用它,但是必须在调用puppeteer.launch的时候显式的指定executablePath(浏览器的执行位置)

    一般来说我会使用这个

代码

建议看这篇文章 结合项目来谈谈 Puppeteer 在结合 github-examples的例子。

注意点

  1. 在部署的时候,建议使用容器化,Chrome本身是内存大户,如果遇到内存飙升,代码是不太好发现这种情况的,不能及时kill掉。

  2. 在加载网页的时候不建议每次都关闭和开启一个新的。

    Chrome的启动和关系是比较耗时的,每次启动会慢150ms到300ms

    建议重复使用同一个Chrome。

  3. Chrome使用一段时间之后,要关掉重启。

    Chrome在我们自己的电脑中有的时候,页面都会崩溃,浏览器也会崩溃。在服务器这种情况下,肯定也会出现,建议在内存中设置调用阈值,比如加载了100个网页,重启一次。这样可降低崩溃的概率。

  4. 容器化部署之后,建议一个容器中只启动一个Chrome。

    这样会让代码简单并且出现问题好排查。这就要求Chrome在代码中是单例

  5. 在整个Chrome做操作期间,对Chrome崩溃的情况做处理

    在业务代码期间,建议使用try catch 来捕获异常,对于非业务异常,需要关闭掉Chrome。防止出现多个Chrome。

  6. Chrome在关闭的时候出现异常,也需要处理

    在调用close()api来关闭Chrome的时候,可能会报错(可能Chrome在这个时候被操作系统kill掉,会出现孤儿进程)。

    建议:在这个时候直接通过shell脚本来强行kill掉

    #!/bin/bashpids=$(ps -ef | grep "[c]hrome" | grep -v 'kill_chrome_processes.sh' |awk '{print $2}')for pid in $pids; doecho "Terminating PID $pid"kill $pid
    doneecho "All chrome processes have been terminated."
    

    孤儿进程:

    父进程启动了子进程,子进程在没有退出的情况下,父进程退出了。此时子进程会被init进程接管。

  7. 尽量关闭掉无用的功能,让他越简单越好。

    比如:-no-sandbox,--disable-extensions,--disable-gpu,--disable_scrollbars

  8. 共享内存

    Chrome 默认使用 /dev/shm 共享内存,但是 docker 默认/dev/shm 只有64MB,显然是不够使用的,提供两种方式来解决:

    • 启动 docker 时添加参数 --shm-size=1gb 来增大 /dev/shm 共享内存,但是 swarm 目前不支持 shm-size 参数
    • 启动 Chrome 添加参数 - disable-dev-shm-usage,禁止使用 /dev/shm 共享内存

参考文档

  • https://www.neovasolutions.com/2022/05/19/browser-automation-tools-protocols-webdriver-vs-cdp/
  • https://dev.to/jankaritech/different-approaches-protocols-to-automate-the-browser-39f1
  • https://stackoverflow.com/questions/50939116/what-is-the-difference-between-webdriver-and-devtool-protocol
  • https://zhuanlan.zhihu.com/p/76237595

关于博客这件事,我是把它当做我的笔记,里面有很多的内容反映了我思考的过程,因为思维有限,不免有些内容有出入,如果有问题,欢迎指出。一同探讨。谢谢。

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

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

相关文章

探索海洋世界,基于DETR(DEtection TRansformer)模型开发构建海洋场景下海洋生物检测识别分析系统

前面的博文中,开发实践过海底相关生物检测识别的项目,对于海洋场景下的海洋生物检测则很少有所涉及,这里本文的主要目的就是想要开发构建基于DETR的海洋场景下的海洋生物检测识别系统。 首先看下实例效果: DETR (DEtection TRans…

【机器学习笔记】 15 机器学习项目流程

机器学习的一般步骤 数据清洗 数据清洗是指发现并纠正数据文件中可识别的错误的最后一道程序,包括检查数据一致性,处理无效值和缺失值等。与问卷审核不同,录入后的数据清理一般是由计算机而不是人工完成。 探索性数据分析(EDA 探索性数据…

Elasticsearch查询报错 Result window is too large

一现象: es数据分页查询前端提示系统异常,后端报错日志 二根本原因: 默认情况下,Elasticsearch 限制了 from size 参数的组合不能超过 10,000 条记录,用于防止查询大数据集时对系统资源的过度消耗 三解决办法&#…

沁恒CH32V30X学习笔记09---使用TIM 外部时钟1模式实现硬件计数

TIM 外部时钟1使用 定时器时钟 通过框图可知;外部时钟1模式下仅仅只有通道1 和通道2 可以输入脉冲 简单示例教程 void TIM1_ETRClockMode1_Init(void) {RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);TIM_CounterModeConfig(TIM1, TIM_CounterMode_Up)

机器学习---强化学习

1. 什么是强化学习 在连接主义学习中,在学习的方式有三种:非监督学习(unsupervised learning)、监督学习 (supervised leaning)和强化学习。监督学习也称为有导师的学习,需要外界存在一个“教师”对给定 输入提供应有的输出结果&#xff0…

Android 11.0 mtp在锁屏模式和息屏时禁止访问mtp文件夹功能实现

1.前言 在11.0的系统rom产品定制化开发中,由于系统对于mtp模式访问文件夹没有限制,就是在锁屏息屏状态下也是可以访问文件夹的,由于产品的需要 要求在锁屏和息屏的情况下,禁止访问文件夹,就是需要实现如图效果 2.mtp在锁屏模式和息屏时禁止访问mtp文件夹功能实现的核心…

【Vue3】路由传参的几种方式

路由导航有两种方式&#xff0c;分别是&#xff1a;声明式导航 和 编程式导航 参数分为query参数和params参数两种 声明式导航 query参数 一、路径字符串拼接(不推荐) 1.传参 在路由路径后直接拼接?参数名:参数值 &#xff0c;多组参数间使用&分隔。 <RouterLink …

unity学习(27)——修改text控件的内容

手游最大的特点就是简单易懂好上手。 1.在canvas上添加一个text的UI&#xff0c;内容设置为空。在字体处添加宋体&#xff0c;增加一个tag。 2.修改LoginHandler中的内容如下&#xff1a;&#xff08;之前有从inputFiled中获取文字的经验&#xff09; public void LoginHandl…

阿里云幻兽帕鲁服务器,游戏服务端版本升级怎么操作?

用阿里云一键部署的幻兽帕鲁服务器&#xff0c;想要更新游戏服务端版本&#xff0c;现在非常简单。之前还需要通过输入一行命令来更新&#xff0c;而现在可以直接通过面板上的选型来操作。 打开阿里云的计算巢&#xff0c;找到你的这台服务实例&#xff0c;点击进入&#xff0…

通过HTTP隧道在Linux上实现跨域资源共享(CORS):打破数字世界的“门禁”

在数字世界里&#xff0c;有时你会碰到一些“门禁”&#xff0c;它们阻止你访问某些资源&#xff0c;就像现实生活中的门禁系统一样。这些“门禁”就是所谓的跨域资源共享&#xff08;CORS&#xff09;限制。不过别担心&#xff0c;我们有一个绝妙的解决方案&#xff1a;通过HT…

模板(函数模板)---C++

模板目录 模板1.模板概念&#xff12;.泛型编程 1.函数模板1.1 函数模板语法1.2 函数模板注意事项1.3 普通函数与函数模板的区别1.4 普通函数与函数模板的调用规则1.5 模板的局限性1.6 函数模板案例 模板 1.模板概念 模板就是建立通用的模具&#xff0c;大大提高复用性。 模板…

安防监控平台EasyCVR升级之后添加通道进行播放,提示“请确认播放协议配置选项”是什么原因?

智慧安防平台EasyCVR能在复杂的网络环境中&#xff08;专网、局域网、广域网、VPN、公网等&#xff09;将前端海量的设备进行统一集中接入与视频汇聚管理&#xff0c;平台可支持的接入协议包括&#xff1a;国标GB28181、RTSP/Onvif、RTMP&#xff0c;以及厂家的私有协议与SDK&a…

文献速递:GAN医学影像合成--联邦生成对抗网络基础医学图像合成中的后门攻击与防御

文献速递&#xff1a;GAN医学影像合成–联邦生成对抗网络基础医学图像合成中的后门攻击与防御 01 文献速递介绍 虽然深度学习在医疗保健研究中产生了显著影响&#xff0c;但其在医疗保健领域的影响无疑比在其他应用领域更慢、更有限。造成这种情况的一个重要原因是&#xff…

码蹄集新手村MT1241-总结

这道题可以通过手写排序算法&#xff0c;完成从大到小排序后再输出 这里提供另外一种思路 了解c中sort()函数。sort()函数可以对给定区间所有元素进行排序。它有三个参数sort(begin, end, cmp)&#xff0c;其中begin为指向待sort()的数组的第一个元素的指针&#xff0c;end为…

政安晨:【完全零基础】认知人工智能(四)【超级简单】的【机器学习神经网络】—— 权重矩阵

预备 如果小伙伴们第一次看到这篇文章&#xff0c;同时也对这类知识还是稍感陌生的话&#xff0c;可以先看看我这个系列的前三篇文章&#xff1a; 政安晨&#xff1a;【完全零基础】认知人工智能&#xff08;一&#xff09;【超级简单】的【机器学习神经网络】 —— 预测机ht…

【ARMv8M Cortex-M33 系列 8 -- RT-Thread 移植 posix pthread】

文章目录 RT-Thread POSIX PthreadRT-Thread Pthread 相关宏定义RT-Thread libc 初始化RT-Thread Pthread 测试 RT-Thread POSIX Pthread pthread是POSIX&#xff08;Portable Operating System Interface&#xff09;标准定义的一套线程相关的API&#xff0c;全称为POSIX Thr…

jenkins离线安装一波

内网安装jenkins对于没有外网的看过来 插件下载神器-jenkins-plugin-manager 首先下载jenkins&#xff0c;官网地址我就不贴了下载完正常运行&#xff0c;开始界面不要选择任何插件安装&#xff0c;选择无去下载一个插件下载工具https://github.com/jenkinsci/plugin-installa…

《Solidity 简易速速上手小册》第1章:Solidity 和智能合约简介(2024 最新版)

文章目录 1.1 Solidity 的起源和重要性1.1.1 基础知识解析1.1.2 重点案例&#xff1a;去中心化金融 (DeFi) 平台案例 Demo&#xff1a;简易借贷平台 1.1.3 拓展案例 1&#xff1a;NFT 市场案例 Demo&#xff1a;简易 NFT 市场 1.1.4 拓展案例 2&#xff1a;智能合约管理的投票系…

C++ 区间合并 算法(详解) + 例题

1、定义 把所有&#xff0c;有交集的区间合并 图解&#xff1a; 2、实现 步骤如下&#xff1a; 1、首先按照每个区间左端点排序 2、扫描 所有区间&#xff0c;进行区间合并 上述第二条&#xff0c;可以理解为&#xff1a;拿出一个区间去跟它后面的所有的区间去进行合并&…

electron Tab加载动画开启和关闭

记个开发中的bug&#xff0c;以此为鉴。眼懒得时候手勤快点儿&#xff0c;不要想当然&#xff01;&#xff01;&#xff01; 没有转载的价值&#xff0c;请勿转载搬运呦。 WebContents API&#xff1a; Event: did-finish-load​ 导航完成时触发&#xff0c;即选项卡的旋转…