@pyrokine/mcp-chrome 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +333 -0
- package/dist/anti-detection/behavior.d.ts +58 -0
- package/dist/anti-detection/behavior.d.ts.map +1 -0
- package/dist/anti-detection/behavior.js +113 -0
- package/dist/anti-detection/behavior.js.map +1 -0
- package/dist/anti-detection/index.d.ts +6 -0
- package/dist/anti-detection/index.d.ts.map +1 -0
- package/dist/anti-detection/index.js +6 -0
- package/dist/anti-detection/index.js.map +1 -0
- package/dist/anti-detection/injection.d.ts +19 -0
- package/dist/anti-detection/injection.d.ts.map +1 -0
- package/dist/anti-detection/injection.js +270 -0
- package/dist/anti-detection/injection.js.map +1 -0
- package/dist/cdp/client.d.ts +73 -0
- package/dist/cdp/client.d.ts.map +1 -0
- package/dist/cdp/client.js +275 -0
- package/dist/cdp/client.js.map +1 -0
- package/dist/cdp/index.d.ts +6 -0
- package/dist/cdp/index.d.ts.map +1 -0
- package/dist/cdp/index.js +6 -0
- package/dist/cdp/index.js.map +1 -0
- package/dist/cdp/launcher.d.ts +42 -0
- package/dist/cdp/launcher.d.ts.map +1 -0
- package/dist/cdp/launcher.js +181 -0
- package/dist/cdp/launcher.js.map +1 -0
- package/dist/core/auto-wait.d.ts +71 -0
- package/dist/core/auto-wait.d.ts.map +1 -0
- package/dist/core/auto-wait.js +165 -0
- package/dist/core/auto-wait.js.map +1 -0
- package/dist/core/errors.d.ts +123 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +226 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/index.d.ts +10 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +10 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/locator.d.ts +130 -0
- package/dist/core/locator.d.ts.map +1 -0
- package/dist/core/locator.js +402 -0
- package/dist/core/locator.js.map +1 -0
- package/dist/core/retry.d.ts +27 -0
- package/dist/core/retry.d.ts.map +1 -0
- package/dist/core/retry.js +51 -0
- package/dist/core/retry.js.map +1 -0
- package/dist/core/session.d.ts +254 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +893 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/types.d.ts +263 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +90 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +121 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/browse.d.ts +92 -0
- package/dist/tools/browse.d.ts.map +1 -0
- package/dist/tools/browse.js +368 -0
- package/dist/tools/browse.js.map +1 -0
- package/dist/tools/cookies.d.ts +75 -0
- package/dist/tools/cookies.d.ts.map +1 -0
- package/dist/tools/cookies.js +230 -0
- package/dist/tools/cookies.js.map +1 -0
- package/dist/tools/evaluate.d.ts +45 -0
- package/dist/tools/evaluate.d.ts.map +1 -0
- package/dist/tools/evaluate.js +85 -0
- package/dist/tools/evaluate.js.map +1 -0
- package/dist/tools/extract.d.ts +213 -0
- package/dist/tools/extract.d.ts.map +1 -0
- package/dist/tools/extract.js +304 -0
- package/dist/tools/extract.js.map +1 -0
- package/dist/tools/index.d.ts +13 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +13 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/input.d.ts +241 -0
- package/dist/tools/input.d.ts.map +1 -0
- package/dist/tools/input.js +325 -0
- package/dist/tools/input.js.map +1 -0
- package/dist/tools/logs.d.ts +57 -0
- package/dist/tools/logs.d.ts.map +1 -0
- package/dist/tools/logs.js +165 -0
- package/dist/tools/logs.js.map +1 -0
- package/dist/tools/manage.d.ts +65 -0
- package/dist/tools/manage.d.ts.map +1 -0
- package/dist/tools/manage.js +270 -0
- package/dist/tools/manage.js.map +1 -0
- package/dist/tools/schema.d.ts +261 -0
- package/dist/tools/schema.d.ts.map +1 -0
- package/dist/tools/schema.js +151 -0
- package/dist/tools/schema.js.map +1 -0
- package/dist/tools/wait.d.ts +203 -0
- package/dist/tools/wait.d.ts.map +1 -0
- package/dist/tools/wait.js +254 -0
- package/dist/tools/wait.js.map +1 -0
- package/package.json +43 -0
- package/scripts/start-chrome-headless.sh +37 -0
- package/scripts/start-chrome.sh +41 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 反检测注入脚本
|
|
3
|
+
*
|
|
4
|
+
* 在页面加载前注入,用于:
|
|
5
|
+
* - 移除 navigator.webdriver
|
|
6
|
+
* - 清理 CDP 痕迹
|
|
7
|
+
* - 模拟真实浏览器指纹
|
|
8
|
+
*
|
|
9
|
+
* 模式:
|
|
10
|
+
* - safe: 最小改动(移除 webdriver、清理 CDP 痕迹)
|
|
11
|
+
* - aggressive: 完整伪装(插件、WebGL、语言等)
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* 获取反检测注入脚本
|
|
15
|
+
*/
|
|
16
|
+
export function getAntiDetectionScript(mode = 'safe') {
|
|
17
|
+
const safeScript = `
|
|
18
|
+
(function() {
|
|
19
|
+
'use strict';
|
|
20
|
+
|
|
21
|
+
// 如果已经注入过,跳过
|
|
22
|
+
if (window.__mcp_chrome_injected__) return;
|
|
23
|
+
window.__mcp_chrome_injected__ = true;
|
|
24
|
+
|
|
25
|
+
// ============================================
|
|
26
|
+
// 1. 移除 navigator.webdriver
|
|
27
|
+
// ============================================
|
|
28
|
+
try {
|
|
29
|
+
Object.defineProperty(navigator, 'webdriver', {
|
|
30
|
+
get: () => undefined,
|
|
31
|
+
configurable: true,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// 删除 webdriver 检测相关属性
|
|
35
|
+
delete navigator.__proto__.webdriver;
|
|
36
|
+
} catch {
|
|
37
|
+
// 静默处理,避免污染站点控制台
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// ============================================
|
|
41
|
+
// 2. 清理 CDP 痕迹
|
|
42
|
+
// ============================================
|
|
43
|
+
try {
|
|
44
|
+
// 清理 window.cdc_* 变量(Chrome DevTools 特征)
|
|
45
|
+
const cdcKeys = Object.keys(window).filter(key => key.startsWith('cdc_'));
|
|
46
|
+
for (const key of cdcKeys) {
|
|
47
|
+
delete window[key];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 清理 document.cdc_* 变量
|
|
51
|
+
const docCdcKeys = Object.keys(document).filter(key => key.startsWith('cdc_'));
|
|
52
|
+
for (const key of docCdcKeys) {
|
|
53
|
+
delete document[key];
|
|
54
|
+
}
|
|
55
|
+
} catch {
|
|
56
|
+
// 静默处理
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ============================================
|
|
60
|
+
// 3. 修改 navigator.userAgent 中的 Headless 标识
|
|
61
|
+
// ============================================
|
|
62
|
+
try {
|
|
63
|
+
const originalUserAgent = navigator.userAgent;
|
|
64
|
+
if (originalUserAgent.includes('HeadlessChrome')) {
|
|
65
|
+
Object.defineProperty(navigator, 'userAgent', {
|
|
66
|
+
get: () => originalUserAgent.replace('HeadlessChrome', 'Chrome'),
|
|
67
|
+
configurable: true,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
} catch {
|
|
71
|
+
// 静默处理
|
|
72
|
+
}
|
|
73
|
+
})();
|
|
74
|
+
`;
|
|
75
|
+
const aggressiveScript = `
|
|
76
|
+
(function() {
|
|
77
|
+
'use strict';
|
|
78
|
+
|
|
79
|
+
// 如果已经注入过,跳过
|
|
80
|
+
if (window.__mcp_chrome_injected__) return;
|
|
81
|
+
window.__mcp_chrome_injected__ = true;
|
|
82
|
+
|
|
83
|
+
// ============================================
|
|
84
|
+
// 1. 移除 navigator.webdriver
|
|
85
|
+
// ============================================
|
|
86
|
+
try {
|
|
87
|
+
Object.defineProperty(navigator, 'webdriver', {
|
|
88
|
+
get: () => undefined,
|
|
89
|
+
configurable: true,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// 删除 webdriver 检测相关属性
|
|
93
|
+
delete navigator.__proto__.webdriver;
|
|
94
|
+
} catch {
|
|
95
|
+
// 静默处理,避免污染站点控制台
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ============================================
|
|
99
|
+
// 2. 清理 CDP 痕迹
|
|
100
|
+
// ============================================
|
|
101
|
+
try {
|
|
102
|
+
// 清理 window.cdc_* 变量(Chrome DevTools 特征)
|
|
103
|
+
const cdcKeys = Object.keys(window).filter(key => key.startsWith('cdc_'));
|
|
104
|
+
for (const key of cdcKeys) {
|
|
105
|
+
delete window[key];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 清理 document.cdc_* 变量
|
|
109
|
+
const docCdcKeys = Object.keys(document).filter(key => key.startsWith('cdc_'));
|
|
110
|
+
for (const key of docCdcKeys) {
|
|
111
|
+
delete document[key];
|
|
112
|
+
}
|
|
113
|
+
} catch {
|
|
114
|
+
// 静默处理
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ============================================
|
|
118
|
+
// 3. 模拟真实插件列表
|
|
119
|
+
// ============================================
|
|
120
|
+
try {
|
|
121
|
+
Object.defineProperty(navigator, 'plugins', {
|
|
122
|
+
get: () => {
|
|
123
|
+
const plugins = [
|
|
124
|
+
{
|
|
125
|
+
name: 'Chrome PDF Plugin',
|
|
126
|
+
filename: 'internal-pdf-viewer',
|
|
127
|
+
description: 'Portable Document Format',
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: 'Chrome PDF Viewer',
|
|
131
|
+
filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai',
|
|
132
|
+
description: '',
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: 'Native Client',
|
|
136
|
+
filename: 'internal-nacl-plugin',
|
|
137
|
+
description: '',
|
|
138
|
+
},
|
|
139
|
+
];
|
|
140
|
+
|
|
141
|
+
// 模拟 PluginArray 行为
|
|
142
|
+
const pluginArray = Object.create(PluginArray.prototype);
|
|
143
|
+
plugins.forEach((plugin, i) => {
|
|
144
|
+
const p = Object.create(Plugin.prototype);
|
|
145
|
+
Object.defineProperties(p, {
|
|
146
|
+
name: { value: plugin.name },
|
|
147
|
+
filename: { value: plugin.filename },
|
|
148
|
+
description: { value: plugin.description },
|
|
149
|
+
length: { value: 0 },
|
|
150
|
+
});
|
|
151
|
+
pluginArray[i] = p;
|
|
152
|
+
});
|
|
153
|
+
Object.defineProperty(pluginArray, 'length', { value: plugins.length });
|
|
154
|
+
pluginArray.item = (i) => pluginArray[i];
|
|
155
|
+
pluginArray.namedItem = (name) => plugins.find(p => p.name === name);
|
|
156
|
+
pluginArray.refresh = () => {};
|
|
157
|
+
|
|
158
|
+
return pluginArray;
|
|
159
|
+
},
|
|
160
|
+
configurable: true,
|
|
161
|
+
});
|
|
162
|
+
} catch {
|
|
163
|
+
// 静默处理
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ============================================
|
|
167
|
+
// 4. 模拟真实语言设置
|
|
168
|
+
// ============================================
|
|
169
|
+
try {
|
|
170
|
+
Object.defineProperty(navigator, 'languages', {
|
|
171
|
+
get: () => ['zh-CN', 'zh', 'en-US', 'en'],
|
|
172
|
+
configurable: true,
|
|
173
|
+
});
|
|
174
|
+
} catch {
|
|
175
|
+
// 静默处理
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// ============================================
|
|
179
|
+
// 5. 修复 Chrome 特有属性
|
|
180
|
+
// ============================================
|
|
181
|
+
try {
|
|
182
|
+
// chrome.runtime 检测
|
|
183
|
+
if (window.chrome === undefined) {
|
|
184
|
+
Object.defineProperty(window, 'chrome', {
|
|
185
|
+
value: {
|
|
186
|
+
runtime: {},
|
|
187
|
+
loadTimes: () => ({}),
|
|
188
|
+
csi: () => ({}),
|
|
189
|
+
app: {
|
|
190
|
+
isInstalled: false,
|
|
191
|
+
InstallState: { DISABLED: 'disabled', INSTALLED: 'installed', NOT_INSTALLED: 'not_installed' },
|
|
192
|
+
RunningState: { CANNOT_RUN: 'cannot_run', READY_TO_RUN: 'ready_to_run', RUNNING: 'running' },
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
configurable: true,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
} catch {
|
|
199
|
+
// 静默处理
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// ============================================
|
|
203
|
+
// 6. 修复 Permissions API
|
|
204
|
+
// ============================================
|
|
205
|
+
try {
|
|
206
|
+
const originalQuery = window.navigator.permissions?.query;
|
|
207
|
+
if (originalQuery) {
|
|
208
|
+
window.navigator.permissions.query = (parameters) => {
|
|
209
|
+
// 对于 notifications 权限,返回 denied 而非 prompt
|
|
210
|
+
if (parameters.name === 'notifications') {
|
|
211
|
+
return Promise.resolve({ state: Notification.permission, onchange: null });
|
|
212
|
+
}
|
|
213
|
+
return originalQuery.call(navigator.permissions, parameters);
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
} catch {
|
|
217
|
+
// 静默处理
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// ============================================
|
|
221
|
+
// 7. 隐藏自动化检测特征
|
|
222
|
+
// ============================================
|
|
223
|
+
try {
|
|
224
|
+
// 修改 navigator.userAgent 中的 Headless 标识
|
|
225
|
+
const originalUserAgent = navigator.userAgent;
|
|
226
|
+
if (originalUserAgent.includes('HeadlessChrome')) {
|
|
227
|
+
Object.defineProperty(navigator, 'userAgent', {
|
|
228
|
+
get: () => originalUserAgent.replace('HeadlessChrome', 'Chrome'),
|
|
229
|
+
configurable: true,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
} catch {
|
|
233
|
+
// 静默处理
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// ============================================
|
|
237
|
+
// 8. 修复 WebGL 渲染器信息
|
|
238
|
+
// ============================================
|
|
239
|
+
try {
|
|
240
|
+
const getParameter = WebGLRenderingContext.prototype.getParameter;
|
|
241
|
+
WebGLRenderingContext.prototype.getParameter = function(parameter) {
|
|
242
|
+
// UNMASKED_VENDOR_WEBGL
|
|
243
|
+
if (parameter === 37445) {
|
|
244
|
+
return 'Intel Inc.';
|
|
245
|
+
}
|
|
246
|
+
// UNMASKED_RENDERER_WEBGL
|
|
247
|
+
if (parameter === 37446) {
|
|
248
|
+
return 'Intel Iris OpenGL Engine';
|
|
249
|
+
}
|
|
250
|
+
return getParameter.call(this, parameter);
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
const getParameter2 = WebGL2RenderingContext.prototype.getParameter;
|
|
254
|
+
WebGL2RenderingContext.prototype.getParameter = function(parameter) {
|
|
255
|
+
if (parameter === 37445) {
|
|
256
|
+
return 'Intel Inc.';
|
|
257
|
+
}
|
|
258
|
+
if (parameter === 37446) {
|
|
259
|
+
return 'Intel Iris OpenGL Engine';
|
|
260
|
+
}
|
|
261
|
+
return getParameter2.call(this, parameter);
|
|
262
|
+
};
|
|
263
|
+
} catch {
|
|
264
|
+
// 静默处理
|
|
265
|
+
}
|
|
266
|
+
})();
|
|
267
|
+
`;
|
|
268
|
+
return mode === 'aggressive' ? aggressiveScript : safeScript;
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=injection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"injection.js","sourceRoot":"","sources":["../../src/anti-detection/injection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAoB,MAAM;IAC7D,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyDtB,CAAA;IAEG,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgM5B,CAAA;IAEG,OAAO,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,UAAU,CAAA;AAChE,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CDP (Chrome DevTools Protocol) 客户端
|
|
3
|
+
*
|
|
4
|
+
* 基于 WebSocket 实现,不依赖 Puppeteer
|
|
5
|
+
* 参考 Puppeteer 的实现原理,但更轻量
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
/**
|
|
9
|
+
* CDP 事件监听器
|
|
10
|
+
*/
|
|
11
|
+
type CDPEventListener = (params: unknown) => void;
|
|
12
|
+
/**
|
|
13
|
+
* CDP 客户端
|
|
14
|
+
*/
|
|
15
|
+
export declare class CDPClient extends EventEmitter {
|
|
16
|
+
/** 默认命令超时 */
|
|
17
|
+
private static readonly DEFAULT_COMMAND_TIMEOUT;
|
|
18
|
+
private ws;
|
|
19
|
+
private callbacks;
|
|
20
|
+
private nextId;
|
|
21
|
+
private eventListeners;
|
|
22
|
+
private _endpoint;
|
|
23
|
+
get endpoint(): string;
|
|
24
|
+
get isConnected(): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* 连接到 CDP 端点
|
|
27
|
+
*/
|
|
28
|
+
connect(endpoint: string, timeout?: number): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* 发送 CDP 命令
|
|
31
|
+
*/
|
|
32
|
+
send<T = unknown>(method: string, params?: object, sessionId?: string, timeout?: number): Promise<T>;
|
|
33
|
+
/**
|
|
34
|
+
* 监听 CDP 事件
|
|
35
|
+
*/
|
|
36
|
+
onEvent(event: string, listener: CDPEventListener): void;
|
|
37
|
+
/**
|
|
38
|
+
* 移除 CDP 事件监听
|
|
39
|
+
*/
|
|
40
|
+
offEvent(event: string, listener: CDPEventListener): void;
|
|
41
|
+
/**
|
|
42
|
+
* 等待特定事件
|
|
43
|
+
*/
|
|
44
|
+
waitForEvent<T = unknown>(event: string, predicate?: (params: T) => boolean, timeout?: number): Promise<T>;
|
|
45
|
+
/**
|
|
46
|
+
* 关闭连接
|
|
47
|
+
*/
|
|
48
|
+
close(): void;
|
|
49
|
+
/**
|
|
50
|
+
* 处理收到的消息
|
|
51
|
+
*/
|
|
52
|
+
private handleMessage;
|
|
53
|
+
/**
|
|
54
|
+
* 处理连接关闭
|
|
55
|
+
*/
|
|
56
|
+
private handleClose;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* 获取浏览器 WebSocket 端点
|
|
60
|
+
*/
|
|
61
|
+
export declare function getBrowserWSEndpoint(host: string, port: number, timeout?: number): Promise<string>;
|
|
62
|
+
/**
|
|
63
|
+
* 获取所有可用的 targets
|
|
64
|
+
*/
|
|
65
|
+
export declare function getTargets(host: string, port: number, timeout?: number): Promise<Array<{
|
|
66
|
+
id: string;
|
|
67
|
+
type: string;
|
|
68
|
+
url: string;
|
|
69
|
+
title: string;
|
|
70
|
+
webSocketDebuggerUrl: string;
|
|
71
|
+
}>>;
|
|
72
|
+
export {};
|
|
73
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/cdp/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAC,YAAY,EAAC,MAAM,QAAQ,CAAA;AAanC;;GAEG;AACH,KAAK,gBAAgB,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;AAElD;;GAEG;AACH,qBAAa,SAAU,SAAQ,YAAY;IACvC,aAAa;IACb,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAQ;IACvD,OAAO,CAAC,EAAE,CAAyB;IACnC,OAAO,CAAC,SAAS,CAAgD;IACjE,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,cAAc,CAAiD;IAEvE,OAAO,CAAC,SAAS,CAAgB;IAEjC,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;OAEG;IACG,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,SAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAgD/D;;OAEG;IACG,IAAI,CAAC,CAAC,GAAG,OAAO,EAClB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,GAAE,MAA0C,GACpD,OAAO,CAAC,CAAC,CAAC;IAoCb;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAOxD;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAOzD;;OAEG;IACH,YAAY,CAAC,CAAC,GAAG,OAAO,EACpB,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,EAClC,OAAO,SAAQ,GAChB,OAAO,CAAC,CAAC,CAAC;IAmBb;;OAEG;IACH,KAAK,IAAI,IAAI;IAeb;;OAEG;IACH,OAAO,CAAC,aAAa;IAiDrB;;OAEG;IACH,OAAO,CAAC,WAAW;CAQtB;AAKD;;GAEG;AACH,wBAAsB,oBAAoB,CACtC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAA6B,GACvC,OAAO,CAAC,MAAM,CAAC,CAyBjB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAA6B,GACvC,OAAO,CACN,KAAK,CAAC;IACF,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,oBAAoB,EAAE,MAAM,CAAC;CAChC,CAAC,CACL,CA8BA"}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CDP (Chrome DevTools Protocol) 客户端
|
|
3
|
+
*
|
|
4
|
+
* 基于 WebSocket 实现,不依赖 Puppeteer
|
|
5
|
+
* 参考 Puppeteer 的实现原理,但更轻量
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
import WebSocket from 'ws';
|
|
9
|
+
import { CDPError, ConnectionRefusedError, TimeoutError } from '../core/errors.js';
|
|
10
|
+
/**
|
|
11
|
+
* CDP 客户端
|
|
12
|
+
*/
|
|
13
|
+
export class CDPClient extends EventEmitter {
|
|
14
|
+
/** 默认命令超时 */
|
|
15
|
+
static DEFAULT_COMMAND_TIMEOUT = 30000;
|
|
16
|
+
ws = null;
|
|
17
|
+
callbacks = new Map();
|
|
18
|
+
nextId = 1;
|
|
19
|
+
eventListeners = new Map();
|
|
20
|
+
_endpoint = '';
|
|
21
|
+
get endpoint() {
|
|
22
|
+
return this._endpoint;
|
|
23
|
+
}
|
|
24
|
+
get isConnected() {
|
|
25
|
+
return this.ws !== null && this.ws.readyState === WebSocket.OPEN;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 连接到 CDP 端点
|
|
29
|
+
*/
|
|
30
|
+
async connect(endpoint, timeout = 30000) {
|
|
31
|
+
this._endpoint = endpoint;
|
|
32
|
+
return new Promise((resolve, reject) => {
|
|
33
|
+
const timer = setTimeout(() => {
|
|
34
|
+
reject(new TimeoutError(`连接超时: ${endpoint} (${timeout}ms)`));
|
|
35
|
+
}, timeout);
|
|
36
|
+
try {
|
|
37
|
+
this.ws = new WebSocket(endpoint);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
clearTimeout(timer);
|
|
41
|
+
// 解析 host 和 port
|
|
42
|
+
const match = endpoint.match(/ws:\/\/([^:]+):(\d+)/);
|
|
43
|
+
if (match) {
|
|
44
|
+
reject(new ConnectionRefusedError(match[1], parseInt(match[2], 10)));
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
reject(new CDPError(`无法连接到 ${endpoint}`));
|
|
48
|
+
}
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
this.ws.on('open', () => {
|
|
52
|
+
clearTimeout(timer);
|
|
53
|
+
resolve();
|
|
54
|
+
});
|
|
55
|
+
this.ws.on('error', (error) => {
|
|
56
|
+
clearTimeout(timer);
|
|
57
|
+
// 解析 host 和 port
|
|
58
|
+
const match = endpoint.match(/ws:\/\/([^:]+):(\d+)/);
|
|
59
|
+
if (match && error.message.includes('ECONNREFUSED')) {
|
|
60
|
+
reject(new ConnectionRefusedError(match[1], parseInt(match[2], 10)));
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
reject(new CDPError(error.message));
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
this.ws.on('message', (data) => {
|
|
67
|
+
this.handleMessage(data);
|
|
68
|
+
});
|
|
69
|
+
this.ws.on('close', () => {
|
|
70
|
+
this.handleClose();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 发送 CDP 命令
|
|
76
|
+
*/
|
|
77
|
+
async send(method, params, sessionId, timeout = CDPClient.DEFAULT_COMMAND_TIMEOUT) {
|
|
78
|
+
if (!this.isConnected) {
|
|
79
|
+
throw new CDPError('CDP 客户端未连接');
|
|
80
|
+
}
|
|
81
|
+
const id = this.nextId++;
|
|
82
|
+
const message = { id, method };
|
|
83
|
+
if (params !== undefined) {
|
|
84
|
+
message.params = params;
|
|
85
|
+
}
|
|
86
|
+
if (sessionId !== undefined) {
|
|
87
|
+
message.sessionId = sessionId;
|
|
88
|
+
}
|
|
89
|
+
return new Promise((resolve, reject) => {
|
|
90
|
+
const timeoutId = setTimeout(() => {
|
|
91
|
+
this.callbacks.delete(id);
|
|
92
|
+
reject(new CDPError(`CDP 命令超时: ${method} (${timeout}ms)`));
|
|
93
|
+
}, timeout);
|
|
94
|
+
this.callbacks.set(id, {
|
|
95
|
+
resolve: (result) => {
|
|
96
|
+
clearTimeout(timeoutId);
|
|
97
|
+
resolve(result);
|
|
98
|
+
},
|
|
99
|
+
reject: (error) => {
|
|
100
|
+
clearTimeout(timeoutId);
|
|
101
|
+
reject(error);
|
|
102
|
+
},
|
|
103
|
+
method,
|
|
104
|
+
});
|
|
105
|
+
this.ws.send(JSON.stringify(message));
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* 监听 CDP 事件
|
|
110
|
+
*/
|
|
111
|
+
onEvent(event, listener) {
|
|
112
|
+
if (!this.eventListeners.has(event)) {
|
|
113
|
+
this.eventListeners.set(event, new Set());
|
|
114
|
+
}
|
|
115
|
+
this.eventListeners.get(event).add(listener);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* 移除 CDP 事件监听
|
|
119
|
+
*/
|
|
120
|
+
offEvent(event, listener) {
|
|
121
|
+
const listeners = this.eventListeners.get(event);
|
|
122
|
+
if (listeners) {
|
|
123
|
+
listeners.delete(listener);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* 等待特定事件
|
|
128
|
+
*/
|
|
129
|
+
waitForEvent(event, predicate, timeout = 30000) {
|
|
130
|
+
return new Promise((resolve, reject) => {
|
|
131
|
+
const timer = setTimeout(() => {
|
|
132
|
+
this.offEvent(event, listener);
|
|
133
|
+
reject(new TimeoutError(`等待事件超时: ${event} (${timeout}ms)`));
|
|
134
|
+
}, timeout);
|
|
135
|
+
const listener = (params) => {
|
|
136
|
+
if (!predicate || predicate(params)) {
|
|
137
|
+
clearTimeout(timer);
|
|
138
|
+
this.offEvent(event, listener);
|
|
139
|
+
resolve(params);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
this.onEvent(event, listener);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* 关闭连接
|
|
147
|
+
*/
|
|
148
|
+
close() {
|
|
149
|
+
// 先拒绝所有等待中的回调
|
|
150
|
+
for (const [id, callback] of this.callbacks) {
|
|
151
|
+
callback.reject(new CDPError('连接主动关闭'));
|
|
152
|
+
}
|
|
153
|
+
this.callbacks.clear();
|
|
154
|
+
this.eventListeners.clear();
|
|
155
|
+
// 关闭 WebSocket
|
|
156
|
+
if (this.ws) {
|
|
157
|
+
this.ws.close();
|
|
158
|
+
this.ws = null;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* 处理收到的消息
|
|
163
|
+
*/
|
|
164
|
+
handleMessage(data) {
|
|
165
|
+
let message;
|
|
166
|
+
try {
|
|
167
|
+
message = JSON.parse(data.toString());
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
console.error('CDP: 无法解析消息', data.toString());
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
// 响应消息
|
|
174
|
+
if (message.id !== undefined) {
|
|
175
|
+
const callback = this.callbacks.get(message.id);
|
|
176
|
+
if (callback) {
|
|
177
|
+
this.callbacks.delete(message.id);
|
|
178
|
+
if (message.error) {
|
|
179
|
+
callback.reject(new CDPError(`${callback.method}: ${message.error.message}`));
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
callback.resolve(message.result);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
// 事件消息
|
|
188
|
+
if (message.method) {
|
|
189
|
+
const listeners = this.eventListeners.get(message.method);
|
|
190
|
+
if (listeners) {
|
|
191
|
+
for (const listener of listeners) {
|
|
192
|
+
try {
|
|
193
|
+
listener(message.params);
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
console.error(`CDP 事件处理错误 (${message.method}):`, error);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// 也触发通用事件
|
|
201
|
+
this.emit(message.method, message.params);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* 处理连接关闭
|
|
206
|
+
*/
|
|
207
|
+
handleClose() {
|
|
208
|
+
// 拒绝所有等待中的回调
|
|
209
|
+
for (const [id, callback] of this.callbacks) {
|
|
210
|
+
callback.reject(new CDPError('连接已关闭'));
|
|
211
|
+
this.callbacks.delete(id);
|
|
212
|
+
}
|
|
213
|
+
this.emit('disconnected');
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/** 默认 HTTP 请求超时 */
|
|
217
|
+
const DEFAULT_HTTP_TIMEOUT = 10000;
|
|
218
|
+
/**
|
|
219
|
+
* 获取浏览器 WebSocket 端点
|
|
220
|
+
*/
|
|
221
|
+
export async function getBrowserWSEndpoint(host, port, timeout = DEFAULT_HTTP_TIMEOUT) {
|
|
222
|
+
const url = `http://${host}:${port}/json/version`;
|
|
223
|
+
const controller = new AbortController();
|
|
224
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
225
|
+
try {
|
|
226
|
+
const response = await fetch(url, { signal: controller.signal });
|
|
227
|
+
if (!response.ok) {
|
|
228
|
+
throw new ConnectionRefusedError(host, port);
|
|
229
|
+
}
|
|
230
|
+
const data = (await response.json());
|
|
231
|
+
return data.webSocketDebuggerUrl;
|
|
232
|
+
}
|
|
233
|
+
catch (error) {
|
|
234
|
+
if (error instanceof ConnectionRefusedError) {
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
// AbortError 表示超时
|
|
238
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
239
|
+
throw new TimeoutError(`连接超时: ${host}:${port} (${timeout}ms)`);
|
|
240
|
+
}
|
|
241
|
+
throw new ConnectionRefusedError(host, port);
|
|
242
|
+
}
|
|
243
|
+
finally {
|
|
244
|
+
clearTimeout(timeoutId);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* 获取所有可用的 targets
|
|
249
|
+
*/
|
|
250
|
+
export async function getTargets(host, port, timeout = DEFAULT_HTTP_TIMEOUT) {
|
|
251
|
+
const url = `http://${host}:${port}/json/list`;
|
|
252
|
+
const controller = new AbortController();
|
|
253
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
254
|
+
try {
|
|
255
|
+
const response = await fetch(url, { signal: controller.signal });
|
|
256
|
+
if (!response.ok) {
|
|
257
|
+
throw new ConnectionRefusedError(host, port);
|
|
258
|
+
}
|
|
259
|
+
return (await response.json());
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
if (error instanceof ConnectionRefusedError) {
|
|
263
|
+
throw error;
|
|
264
|
+
}
|
|
265
|
+
// AbortError 表示超时
|
|
266
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
267
|
+
throw new TimeoutError(`连接超时: ${host}:${port} (${timeout}ms)`);
|
|
268
|
+
}
|
|
269
|
+
throw new ConnectionRefusedError(host, port);
|
|
270
|
+
}
|
|
271
|
+
finally {
|
|
272
|
+
clearTimeout(timeoutId);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/cdp/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cdp/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAC,SAAS,EAAE,oBAAoB,EAAE,UAAU,EAAC,MAAM,aAAa,CAAA;AACvE,OAAO,EAAC,eAAe,EAAE,UAAU,EAAC,MAAM,eAAe,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cdp/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAC,SAAS,EAAE,oBAAoB,EAAE,UAAU,EAAC,MAAM,aAAa,CAAA;AACvE,OAAO,EAAC,eAAe,EAAE,UAAU,EAAC,MAAM,eAAe,CAAA"}
|