CDP 专题 - Chrome DevTools Protocol 调用指南
📖 目录
概述
Chrome DevTools Protocol (CDP) 是 Chromium 浏览器提供的底层调试和控制协议。cWebView2Host 支持 VB6 直接调用 CDP,实现对浏览器行为的深度控制,远超 WebView2 公开 API 的能力范围。
✨ 核心特点
- 🔧 同步/异步双模式 - 简单场景用同步调用获取结果,复杂场景用异步避免阻塞
- 🍪 HttpOnly Cookie - 通过 CDP 获取 JavaScript 无法读取的 HttpOnly Cookie
- 📸 截图捕获 - 调用 Page.captureScreenshot 实现页面截图
- 🔍 DOM 深度操作 - 直接操控 DOM 树,不经过 JavaScript 层
- 🌐 网络控制 - 拦截和修改网络请求/响应
同步调用
CallDevToolsProtocolMethodSync
阻塞当前线程直到 CDP 返回结果,最简单的使用方式:
vb
Public Function CallDevToolsProtocolMethodSync( _
ByVal MethodName As String, _
ByVal ParametersAsJson As String) As String返回: CDP 响应的 JSON 字符串
内部机制: 使用 Sleep + DoEvents 循环等待,不影响 VB6 窗体消息循环。
示例:
vb
Dim wv As New cWebView2Host ' 同步调用无需 WithEvents
Private Sub Form_Load()
wv.Initialize Me.hWnd, "https://vb6.pro"
End Sub
Private Sub Command1_Click()
' 获取页面标题
Dim title As String
title = wv.CallDevToolsProtocolMethodSync( _
"Runtime.evaluate", _
"{""expression"":""document.title""}")
MsgBox "Title: " & title
' 获取所有 Cookie
Dim cookies As String
cookies = wv.CallDevToolsProtocolMethodSync( _
"Network.getCookies", _
"{}")
' 获取浏览器版本
Dim version As String
version = wv.CallDevToolsProtocolMethodSync( _
"Browser.getVersion", _
"{}")
End Sub何时使用同步模式
- 简单的查询操作(获取属性、Cookie 等)
- 需要立即获取结果继续后续逻辑
- 不关心 UI 阻塞(或阻塞时间极短)
异步调用
CallDevToolsProtocolMethod
发起 CDP 调用后立即返回,结果通过事件异步回报:
vb
Public Sub CallDevToolsProtocolMethod( _
ByVal MethodName As String, _
ByVal ParametersAsJson As String, _
ByVal CustomEventId As String)参数:
CustomEventId- 自定义事件 ID,在DevToolsProtocolResponse事件中用于匹配响应
示例:
vb
Dim WithEvents wv As cWebView2Host ' 异步需要 WithEvents
Private Sub Command1_Click()
' 发起多个异步 CDP 调用
wv.CallDevToolsProtocolMethod "Page.captureScreenshot", "{}", "screenshot"
wv.CallDevToolsProtocolMethod "DOM.getDocument", "{}", "domDoc"
wv.CallDevToolsProtocolMethod "Runtime.evaluate", _
"{""expression"":""document.URL""}", "pageUrl"
End Sub
Private Sub wv_DevToolsProtocolResponse(ByVal CustomEventId As Variant, ByVal JsonResponse As String)
Select Case CustomEventId
Case "screenshot"
Debug.Print "Screenshot data received"
' JsonResponse 包含 base64 编码的截图数据
Case "domDoc"
Debug.Print "DOM document: " & Left(JsonResponse, 200)
Case "pageUrl"
Debug.Print "Page URL: " & JsonResponse
End Select
End Sub何时使用异步模式
- 耗时操作(截图、大量 DOM 操作)
- 需要同时发起多个 CDP 调用
- 不希望阻塞 UI 线程
常用 CDP 方法
Runtime 域
| 方法 | 参数 | 用途 |
|---|---|---|
Runtime.evaluate | {expression, returnByValue?, awaitPromise?} | 执行 JS 表达式 |
Runtime.callFunctionOn | {functionDeclaration, objectId, arguments, returnByValue} | 在指定对象上调用函数 |
Runtime.getProperties | {objectId, ownProperties} | 获取对象属性 |
Network 域
| 方法 | 参数 | 用途 |
|---|---|---|
Network.getCookies | {urls?} | 获取 Cookie(含 HttpOnly) |
Network.getAllCookies | {} | 获取所有 Cookie |
Network.deleteCookies | {name, url?, domain?, path?} | 删除 Cookie |
Network.setCookie | {name, value, url?, domain?, path?, httpOnly?, secure?} | 设置 Cookie |
Network.setExtraHTTPHeaders | {headers} | 设置额外 HTTP 头 |
Page 域
| 方法 | 参数 | 用途 |
|---|---|---|
Page.captureScreenshot | {format?, quality?, clip?} | 页面截图 |
Page.printToPDF | {landscape?, paperWidth?, ...} | 打印为 PDF |
Page.navigate | {url, referrer?} | 导航 |
Page.reload | {ignoreCache?} | 重新加载 |
DOM 域
| 方法 | 参数 | 用途 |
|---|---|---|
DOM.getDocument | {depth?} | 获取文档根节点 |
DOM.querySelector | {nodeId, selector} | CSS 选择器查询 |
DOM.getOuterHTML | {nodeId} | 获取元素 HTML |
DOM.setAttributeValue | {nodeId, name, value} | 设置属性值 |
Browser 域
| 方法 | 参数 | 用途 |
|---|---|---|
Browser.getVersion | {} | 获取浏览器版本信息 |
Cookie 操作
简易模式 (cWebView2Cookies)
vb
' document.cookie 解析(不含 HttpOnly)
Dim simple As String
simple = wv.Cookies.GetCookies
' CDP Network.getCookies(含 HttpOnly,同步)
Dim full As String
full = wv.Cookies.GetCookiesFull完整 CDP Cookie 操作
vb
' 获取所有 Cookie(含详细信息)
Dim cookies As String
cookies = wv.CallDevToolsProtocolMethodSync("Network.getAllCookies", "{}")
' 返回格式: {"result":{"cookies":[{name,value,domain,path,httpOnly,secure,...}]}}
' 设置 Cookie
wv.CallDevToolsProtocolMethodSync "Network.setCookie", _
"{""name"":""token"",""value"":""abc123"",""domain"":"".example.com"",""httpOnly"":true}"
' 删除 Cookie
wv.CallDevToolsProtocolMethodSync "Network.deleteCookies", _
"{""name"":""token"",""domain"":"".example.com""}"性能与限制
同步调用超时
CallDevToolsProtocolMethodSync 默认超时为 5 秒。对于耗时的 CDP 操作(如截图),建议使用异步模式。
CDP 版本兼容
CDP 方法可用性取决于 WebView2 Runtime 版本。建议使用 Browser.getVersion 检查版本:
vb
Dim version As String
version = wv.CallDevToolsProtocolMethodSync("Browser.getVersion", "{}")
' 返回包含 product、protocolVersion 等字段调用频率
CDP 调用比 JS 执行更重,应避免在循环中高频调用。对于批量操作,优先使用单次 JS 执行:
vb
' 避免:循环中大量 CDP 调用
For i = 0 To 100
wv.CallDevToolsProtocolMethodSync "DOM.setAttributeValue", ...
Next
' 推荐:单次 JS 执行
wv.JsRun "document.querySelectorAll('.item').forEach(el => el.classList.add('active'))"完整示例
页面截图
vb
Private Sub Command1_Click()
wv.CallDevToolsProtocolMethod "Page.captureScreenshot", _
"{""format"":""png""}", "screenshot"
End Sub
Private Sub wv_DevToolsProtocolResponse(ByVal CustomEventId As Variant, ByVal JsonResponse As String)
If CustomEventId = "screenshot" Then
' JsonResponse 包含 base64 编码的 PNG 数据
' 解析并保存到文件...
Debug.Print "Screenshot received, length: " & Len(JsonResponse)
End If
End Sub网络请求拦截
vb
' 设置额外请求头
wv.CallDevToolsProtocolMethodSync "Network.setExtraHTTPHeaders", _
"{""headers"":{""X-Custom-Header"":""MyValue""}}"修改 DOM 属性
vb
' 通过 CDP 修改元素属性
Dim result As String
result = wv.CallDevToolsProtocolMethodSync("Runtime.evaluate", _
"{""expression"":""document.getElementById('title').textContent = 'New Title'""}")最后更新: 2026-06-24