type
status
date
slug
summary
tags
category
icon
password
一.概述
CDP
Chrome DevTools Protocol 允许工具对基于 Chromium、Chrome 以及其他基于 Blink 的浏览器进行检查/调试/监听网络流量。Chrome DevTools 使用这个协议,且该团队维护其 API。
交流方式
通过 HTTP, WebSocket 两种方式, 对添加了远程调试接口参数(
--remote-debugging-port=9222
)的浏览器进行远程调试, 大部分功能其实与浏览器手机打开的 devtools 一致- HTTP 负责总览当前 Tabs 信息
- WebSocket 负责与每个Tab 的对话建立连接,并接收已开启功能 (enabled domain) 的事件消息。
二.启动参数:
参数 | ㅤ |
--remote-debugging-host=%s | 启用远程调试 ip |
--remote-debugging-port=%s | 启用远程调试 端口 |
--user-data-dir=%s | 浏览器存储用户配置文件的目录 |
--disk-cache-dir=%s | 浏览器缓存目录 |
--lang=%s | 语言 |
--disable-gpu | 禁用GPU硬件加速 |
--load-extension=A,B | 加载插件,多个以,分割 |
--proxy-server=%s | 代理 |
--no-default-browser-check | 关闭chrome是否设为默认浏览器的提示 |
--no-first-run | 跳过 Chromium 首次运行检查 |
--no-sandbox | 为所有通常使用沙盒的进程类型禁用沙盒。仅用于测试目的的浏览器级开关。 |
--headless=new | 在无头模式下运行 |
--window-size=1920,1080 | 窗口大小 |
代码实现
启动命令
/usr/bin/google-chrome --disable-gpu --window-size=1920,1080 --start-maximized --remote-debugging-host=127.0.0.1 --remote-debugging-port=48159 --remote-allow-origins=* --user-data-dir=/tmp/tmpyw0sqgy1 --lang=zh-CN --no-default-browser-check --no-first-run --no-sandbox --test-type --log-level=0/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --disable-gpu --window-size=1920,1080 --start-maximized --remote-debugging-host=127.0.0.1 --remote-debugging-port=48159 --user-data-dir=/tmp/tmpyw0sqgy1 --lang=zh-CN --no-default-browser-check --no-first-run --no-sandbox --test-type --log-level=0
三.Domain
在CDP中,“Domain”指的是一组可通过协议进行操作的功能区域或API集。每个Domain包含了一系列的方法(Methods)和事件(Events),这些方法和事件用于控制和监视浏览器的不同方面。例如,有针对页面操作的“Page”域、处理DOM结构的“DOM”域、网络请求的“Network”域等。
这些域允许开发者通过CDP与浏览器的各个部分交互,实现自动化测试、性能分析、调试等功能。每个域都独立负责特定的功能,开发者可以根据需要启用和使用这些域。
Page Domain
简单地理解, 可以把一个 Page 看成一个 Page 类型的 Tab,可以操控Tab进行刷新、跳转、停止、激活、截图等功能,并且通过监听事件来判断页面状态(是否加载完成)。
Page.enable | Methods | 允许客户端接收页面相关的事件,如页面加载、页面渲染完成、JavaScript执行错误等。 |
Page.disable | Methods | 禁止客户端接收页面相关的事件 |
Page.frameStoppedLoading | Events | 停止加载时触发。标志完成文档的加载 |
Page.frameStartedLoading | Events | 当框架开始加载时触发 |
Page.loadEventFired | Events | 页面的 load 事件已经被触发。当整个页面及所有依赖的资源(如图片、CSS文件)都已完全加载时 |
Page.frameNavigated | Events | 框架导航完成后触发(即URL变化) |
Page.captureScreenshot | Methods | 截图 |
Page.printToPDF | Methods | 保存成pdf |
Page.navigate | Methods | 导航当前页面到指定的URL |
DOM Domain
可以操作DOM的读写操作。每个DOM节点都通过一个带有ID的镜像对象表示。这个ID可以用来获取节点的额外信息,将其解析为JavaScript对象包装器等。
此外,对于iframe元素,其“所有者”元素(即包含iframe的元素)会将iframe内容的文档节点视作自己的子节点返回。这意味着通过DOM操作或查询时,iframe内部的文档被视为其父iframe元素的直接子节点,这对于处理嵌套文档的DOM操作很重要。
DOM.enable | Methods | ㅤ |
DOM.disable | Methods | ㅤ |
DOM.getDocument | Methods | 返回根DOM节点#### |
DOM.querySelector | Methods | 根据指定的CSS选择器在给定的节点上查找第一个匹配的元素。(返回nodeid) |
DOM.querySelectorAll | Methods | 根据指定的CSS选择器在给定的节点上查找所有匹配的元素。(返回nodeid) |
DOM.performSearch | Methods | 在DOM树中搜索给定的字符串。使用getSearchResults获取搜索结果,或使用cancelSearch结束这次搜索会话#### |
DOM.getSearchResults | Methods | 根据给定的标识符,返回从fromIndex到toIndex的搜索结果 |
DOM.discardSearchResults | Methods | 丢弃具有给定ID的会话中的搜索结果。不应再为那次搜索调用getSearchResults。 |
DOM.describeNode | Methods | 根据其ID描述节点#### |
DOM.resolveNode | Methods | 为给定的NodeId或BackendNodeId解析JavaScript节点对象,我们用来获取objectId |
DOM.getOuterHTML | Methods | 返回节点的HTML标记 |
DOM.getAttributes | Methods | 获取节点属性 |
Network Domain
允许跟踪页面的网络活动。它公开关于HTTP、文件、数据及其他请求和响应的信息,包括它们的头部、正文、时间等信息。
Network.disable | Methods | ㅤ | ㅤ |
Network.enable | Methods | ㅤ | ㅤ |
Network.clearBrowserCache | Methods | ㅤ | ㅤ |
Network.clearBrowserCookies | Methods | ㅤ | ㅤ |
Network.requestWillBeSent | Events | 当页面即将发送HTTP请求时触发 | ㅤ |
Network.responseReceived | Events | 当HTTP响应可用时触发 | ㅤ |
Network.loadingFinished | Events | 当HTTP请求完成加载时触发 | ㅤ |
Network.loadingFailed | Events | 当HTTP请求加载失败时触发 | ㅤ |
Network.webSocketFrameReceived | Events | 当接收到WebSocket消息时触发 | |
Network.getRequestPostData | Methods | 根据requestId获取PostData | ㅤ |
Network.getResponseBody | Methods | 根据requestId获取ResponseBody | ㅤ |
Network.replayXHR | Methods | 重发 | ㅤ |
Runtime Domain
Runtime Domain通过远程评估和镜像对象的方式暴露JavaScript运行时。
Runtime.evaluate | Methods | 在全局对象上执行js |
Runtime.callFunctionOn | Methods | 在给定对象执行js |
Input Domain
Input.dispatchMouseEvent | Methods | 向页面派发一个鼠标事件,mousePressed(鼠标按下),mouseReleased(鼠标释放),mouseMoved(鼠标移动),mouseWheel(鼠标滚轮) | ㅤ |
Input.insertText | Methods | 这个方法模拟插入不来源于按键的文本,例如表情符号键盘或输入法编辑器(IME) | 注意:输入前需要获取聚焦给定的元素,cdp = DOM.focus |
Input.dispatchKeyEvent | Methods | 向页面派发一个键盘事件 | 同上 |
ㅤ | ㅤ | ㅤ | ㅤ |
四.工具
点击 DevTools 右上角的齿轮图标以打开设置面板。在设置的左侧选择“实验”。开启“协议监视器”,然后关闭并重新打开 DevTools。现在点击 ⋮ 菜单图标,选择“更多工具”,然后选择“协议监视器”。
还可以使用协议监视器发出自己的命令。如果该命令不需要任何参数,请在“协议监视器”面板底部的提示符中键入该命令。
比如我们想在使用cdp协议截个图。
五.代码
1.Driver
这个类是驱动程序的核心,用于与浏览器标签页的通信。
GenericAttr 类
这个类主要用于动态处理属性访问和设置。它将属性操作代理到另一个对象,通常是一个标签页(tab)对象。
- 构造函数:接收一个名称和标签页对象。名称用来构造方法调用时使用的全名。
__getattr__
:这是一个特殊方法,当试图访问一个不存在的属性时被调用。它会查找是否存在以该属性名命名的事件监听器,如果存在则返回该监听器,否则返回一个使用该名称的部分应用函数,该函数可以调用相应的方法。
__setattr__
:用于在标签页对象上设置事件监听器。
Driver 类
这个类是驱动程序的核心,用于管理与浏览器标签页的通信和控制。
- 属性:
status_initial
,status_started
,status_stopped
:定义了驱动的三种状态。- 其他内部属性用于管理网络连接、事件处理和命令发送。
- 方法:
__init__
:初始化驱动程序,设置标签页ID、类型、地址等,并准备网络连接。run
:执行一个Chrome DevTools Protocol(CDP)方法,处理响应和错误。_send
:负责发送消息到WebSocket,并管理响应队列。_recv_loop
:在后台线程中运行,不断接收WebSocket消息,并处理它们。_handle_event_loop
:处理从WebSocket接收到的事件消息。start
和stop
:用于启动和停止与WebSocket的连接。set_callback
和set_listener
:用于设置事件的回调处理。wait
:等待驱动停止或超时。
整体代码
2.ChromeDriver
用于启动Chrome浏览器,获取tab ws地址,启动Driver,并且使用cdp进行页面元素交互。
3.WebElement
Element 相关操作l类,获取标签,点击,操作。
4.ChromeOptions
Chrome启动参数
六.项目参考
- 作者:404False
- 链接:https://blog.404nofoundx.top//article/4debf43f-d511-4b8e-abf6-e1bc82a6a82d
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。