第一章、Chrome DevTools Protocol (CDP) 详解

Chrome DevTools Protocol (CDP) 详解

一、概述

Chrome DevTools Protocol(简称 CDP)是 Chrome 浏览器提供的远程调试协议,它允许外部程序通过 WebSocket 连接与 Chrome 进行双向通信,从而程序化地控制浏览器行为。Chrome DevTools 本身就是通过这个协议与浏览器交互的。

二、架构

code复制

scss 复制代码
┌─────────────┐    WebSocket     ┌──────────────────┐
│  外部客户端   │ ◄──────────────► │  Chrome Browser  │
│ (Node/Python) │   JSON-RPC      │  (DevTools Agent) │
└─────────────┘                   └──────────────────┘

核心组成:

组件 说明
DevTools Frontend Chrome 开发者工具 UI
DevTools Agent 浏览器内嵌的协议服务端
WebSocket 通道 通信载体,基于 JSON-RPC 2.0

三、连接方式

1. 启动带调试端口的 Chrome

bash复制

ini 复制代码
# macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --remote-debugging-port=9222

# 指定用户数据目录(避免冲突)
--user-data-dir=/tmp/chrome-debug

2. 发现可调试目标

bash复制

bash 复制代码
curl http://localhost:9222/json

返回类似:

json复制

css 复制代码
[ {   "description": "",   "devtoolsFrontendUrl": "...",   "id": "ABC123",   "title": "New Tab",   "type": "page",   "url": "chrome://newtab/",   "webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/ABC123"}]

3. 建立 WebSocket 连接

javascript复制

javascript 复制代码
const WebSocket = require('ws');
const ws = new WebSocket('ws://localhost:9222/devtools/page/ABC123');

ws.on('open', () => {
  // 发送 CDP 命令
  ws.send(JSON.stringify({
    id: 1,
    method: 'Page.navigate',
    params: { url: 'https://example.com' }
  }));
});

ws.on('message', (data) => {
  console.log(JSON.parse(data));
});

四、协议格式

CDP 基于 JSON-RPC 2.0,有两种消息类型:

1. 请求/响应(Command)

json复制

json 复制代码
// 请求
{
  "id": 1,
  "method": "Runtime.evaluate",
  "params": {
    "expression": "document.title"
  }
}

// 响应
{
  "id": 1,
  "result": {
    "result": {
      "type": "string",
      "value": "Example Domain"
    }
  }
}

2. 事件(Event)

json复制

json 复制代码
{
  "method": "Network.responseReceived",
  "params": {
    "requestId": "1001",
    "response": {
      "url": "https://example.com/api",
      "status": 200,
      "mimeType": "application/json"
    }
  }
}

五、核心域(Domains)

CDP 将功能划分为多个域,每个域包含方法(Methods)和事件(Events):

域 用途 常用方法
Page 页面操作 navigate, reload, captureScreenshot
Runtime JS 执行环境 evaluate, callFunctionOn, enable
Network 网络监控 enable, requestWillBeSent, getResponseBody
DOM DOM 操作 getDocument, querySelector, setAttributeValue
CSS 样式操作 getComputedStyleForNode, addRule
Emulation 设备模拟 setDeviceMetricsOverride, setTouchEmulationEnabled
Input 输入模拟 dispatchMouseEvent, dispatchKeyEvent, insertText
Target 目标管理 getTargets, createTarget, attachToTarget
Security 安全控制 handleCertificateError, setOverrideCertificateErrors
Performance 性能监控 enable, getMetrics
Console 控制台 enable, messageAdded

六、常用场景与示例

1. 截图

json复制

json 复制代码
{
  "id": 1,
  "method": "Page.captureScreenshot",
  "params": {
    "format": "png",
    "quality": 90
  }
}

2. 执行 JavaScript

json复制

json 复制代码
{
  "id": 2,
  "method": "Runtime.evaluate",
  "params": {
    "expression": "document.querySelectorAll('a').length",
    "returnByValue": true
  }
}

3. 监控网络请求

json复制

json 复制代码
// 1. 启用网络域
{ "id": 1, "method": "Network.enable" }

// 2. 监听事件 → Network.requestWillBeSent
// 3. 监听事件 → Network.responseReceived
// 4. 获取响应体
{
  "id": 2,
  "method": "Network.getResponseBody",
  "params": { "requestId": "xxx" }
}

4. 模拟点击

json复制

json 复制代码
{
  "id": 1,
  "method": "Input.dispatchMouseEvent",
  "params": {
    "type": "mousePressed",
    "x": 100,
    "y": 200,
    "button": "left",
    "clickCount": 1
  }
}
{
  "id": 2,
  "method": "Input.dispatchMouseEvent",
  "params": {
    "type": "mouseReleased",
    "x": 100,
    "y": 200,
    "button": "left",
    "clickCount": 1
  }
}

七、主流工具库

工具 语言 特点
Puppeteer Node.js Google 官方,高级 API 封装,最流行
Playwright Node/Python/Java/.NET 跨浏览器,API 更现代
chrome-remote-interface Node.js CDP 的底层薄封装,灵活
CDP4J Java Java 生态的 CDP 客户端
Pyppeteer Python Puppeteer 的 Python 移植版

Puppeteer 示例

javascript复制

javascript 复制代码
const puppeteer = require('puppeteer');

const browser = await puppeteer.launch({
  headless: true,
  args: ['--remote-debugging-port=9222']
});

// Puppeteer 内部就是通过 CDP 与浏览器通信
const page = await browser.newPage();

// 可以直接访问 CDP Session
const cdp = await page.createCDPSession();
await cdp.send('Network.enable');
cdp.on('Network.requestWillBeSent', (e) => {
  console.log('Request:', e.params.request.url);
});

await page.goto('https://example.com');

八、高级特性

1. 多 Target 管理

json复制

json 复制代码
// 获取所有可调试目标
{ "id": 1, "method": "Target.getTargets" }

// 创建新标签页
{
  "id": 2,
  "method": "Target.createTarget",
  "params": { "url": "https://example.com" }
}

// 附加到指定目标
{
  "id": 3,
  "method": "Target.attachToTarget",
  "params": { "targetId": "ABC123", "flatten": true }
}

2. 设备模拟

json复制

json 复制代码
{
  "id": 1,
  "method": "Emulation.setDeviceMetricsOverride",
  "params": {
    "width": 375,
    "height": 812,
    "deviceScaleFactor": 3,
    "mobile": true
  }
}

3. 拦截和修改请求

json复制

json 复制代码
// 启用请求拦截
{ "id": 1, "method": "Network.setRequestInterception", "params": { "patterns": [{ "urlPattern": "*.js" }] } }

// 在事件 Network.requestIntercepted 中决定继续或修改
{
  "id": 2,
  "method": "Network.continueInterceptedRequest",
  "params": {
    "interceptionId": "xxx",
    "rawResponse": "<base64 encoded response>"
  }
}

九、安全注意事项

风险 说明
端口暴露 调试端口可被同网络机器访问,生产环境禁止开启
代码执行 CDP 可执行任意 JS,等价于完全控制浏览器
Cookie 窃取 可通过 Network.getCookies 获取所有 Cookie
建议 仅绑定 127.0.0.1,使用后关闭端口

十、协议文档


CDP 是浏览器自动化、爬虫、性能测试、UI 测试等场景的底层基石。Puppeteer 和 Playwright 等工具虽然提供了更友好的高层 API,但理解 CDP 本身能让你在遇到复杂需求时(如拦截请求、注入代码、监控性能指标)直接操作协议层面,获得最大灵活性。

以上就是 Chrome DevTools Protocol 的完整介绍。如果你对某个具体域(如 Network 拦截、Performance 监控)或实战场景(爬虫、自动化测试)有更深入的需求,可以继续问我!

相关推荐
Lank_M几秒前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写2 分钟前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李4 分钟前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易18 分钟前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
清晨Coding22 分钟前
删了 Cookie 还能自动登录?Google系网站登录态自动恢复的原理分析
javascript
风骏时光牛马29 分钟前
前沿视界
前端
kyriewen33 分钟前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员
陈随易1 小时前
3000 万人在用的翻译插件,重写一遍就是一门生意
前端·后端·程序员
IT_陈寒1 小时前
Vue的这个响应式陷阱,差点让我加班到天亮
前端·人工智能·后端
程序员大阳2 小时前
HTML+CSS+JS对话式实战(9)-项目总结与问题分析
javascript·css·html·实战·项目总结