第一章、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 监控)或实战场景(爬虫、自动化测试)有更深入的需求,可以继续问我!

相关推荐
kyriewen2 小时前
从本地到生产:迁移到 GitHub Actions 自动化 CI/CD,总结了这 5 个坑
前端·github·自动化运维
雨季mo浅忆2 小时前
首个Vue3项目边写边学边记
前端·vue3
IT_陈寒3 小时前
React中useEffect依赖项这个坑我居然踩了三天
前端·人工智能·后端
qq4356947013 小时前
Vue04
前端·vue.js
Yeats_Liao4 小时前
Feed流系统设计(三):数据模型与存储设计,从表结构到Redis收件箱
java·javascript·redis
我是真菜4 小时前
彻底理解js中的深浅拷贝
前端·javascript
江畔柳前堤5 小时前
github实战指南07-CLI 与高级技巧
前端·人工智能·chrome·深度学习·github·caffe·issue
kisdiem5 小时前
ReAct:让大模型一边推理,一边行动
前端·react.js·前端框架
西部荒野子5 小时前
JS 如何跑进两个原生世界
前端