deepspider 0.3.0 → 0.3.2
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/.env.example +3 -0
- package/README.md +13 -13
- package/package.json +6 -6
- package/src/agent/core/PanelBridge.js +29 -77
- package/src/agent/core/StreamHandler.js +139 -14
- package/src/agent/index.js +51 -12
- package/src/agent/logger.js +184 -9
- package/src/agent/middleware/report.js +42 -16
- package/src/agent/middleware/subagent.js +233 -0
- package/src/agent/middleware/toolGuard.js +77 -0
- package/src/agent/middleware/validationWorkflow.js +171 -0
- package/src/agent/prompts/system.js +181 -59
- package/src/agent/run.js +41 -6
- package/src/agent/skills/crawler/SKILL.md +64 -3
- package/src/agent/skills/crawler/evolved.md +9 -1
- package/src/agent/skills/dynamic-analysis/SKILL.md +74 -7
- package/src/agent/skills/env/SKILL.md +75 -0
- package/src/agent/skills/evolve.js +0 -3
- package/src/agent/skills/sandbox/SKILL.md +35 -0
- package/src/agent/skills/static-analysis/SKILL.md +98 -2
- package/src/agent/subagents/anti-detect.js +10 -20
- package/src/agent/subagents/captcha.js +7 -19
- package/src/agent/subagents/crawler.js +25 -37
- package/src/agent/subagents/factory.js +109 -9
- package/src/agent/subagents/index.js +4 -13
- package/src/agent/subagents/js2python.js +7 -19
- package/src/agent/subagents/reverse.js +180 -0
- package/src/agent/tools/analysis.js +84 -1
- package/src/agent/tools/anti-detect.js +5 -2
- package/src/agent/tools/browser.js +160 -0
- package/src/agent/tools/captcha.js +1 -1
- package/src/agent/tools/capture.js +24 -3
- package/src/agent/tools/correlate.js +129 -15
- package/src/agent/tools/crawler.js +2 -1
- package/src/agent/tools/crawlerGenerator.js +90 -0
- package/src/agent/tools/debug.js +43 -6
- package/src/agent/tools/evolve.js +6 -3
- package/src/agent/tools/extractor.js +5 -1
- package/src/agent/tools/file.js +16 -7
- package/src/agent/tools/generateHook.js +66 -0
- package/src/agent/tools/hookManager.js +19 -9
- package/src/agent/tools/index.js +33 -20
- package/src/agent/tools/nodejs.js +41 -6
- package/src/agent/tools/python.js +4 -4
- package/src/agent/tools/report.js +2 -2
- package/src/agent/tools/runtime.js +1 -1
- package/src/agent/tools/sandbox.js +21 -1
- package/src/agent/tools/scratchpad.js +70 -0
- package/src/agent/tools/tracing.js +26 -0
- package/src/agent/tools/verifyAlgorithm.js +117 -0
- package/src/analyzer/EncryptionAnalyzer.js +2 -2
- package/src/browser/EnvBridge.js +27 -13
- package/src/browser/client.js +124 -18
- package/src/browser/collector.js +101 -22
- package/src/browser/defaultHooks.js +3 -1
- package/src/browser/hooks/index.js +5 -0
- package/src/browser/interceptors/AntiDebugInterceptor.js +132 -0
- package/src/browser/interceptors/NetworkInterceptor.js +77 -13
- package/src/browser/interceptors/ScriptInterceptor.js +34 -9
- package/src/browser/interceptors/index.js +1 -0
- package/src/browser/ui/analysisPanel.js +469 -464
- package/src/cli/commands/config.js +11 -3
- package/src/config/paths.js +9 -1
- package/src/config/settings.js +7 -1
- package/src/core/PatchGenerator.js +26 -6
- package/src/core/Sandbox.js +140 -3
- package/src/env/EnvCodeGenerator.js +60 -88
- package/src/env/modules/bom/history.js +6 -0
- package/src/env/modules/bom/location.js +6 -0
- package/src/env/modules/bom/navigator.js +13 -0
- package/src/env/modules/bom/screen.js +6 -0
- package/src/env/modules/bom/storage.js +7 -0
- package/src/env/modules/dom/document.js +14 -0
- package/src/env/modules/dom/event.js +4 -0
- package/src/env/modules/index.js +27 -10
- package/src/env/modules/webapi/fetch.js +4 -0
- package/src/env/modules/webapi/url.js +4 -0
- package/src/env/modules/webapi/xhr.js +8 -0
- package/src/store/DataStore.js +130 -47
- package/src/store/Store.js +2 -1
- package/src/agent/subagents/dynamic.js +0 -64
- package/src/agent/subagents/env-agent.js +0 -82
- package/src/agent/subagents/sandbox.js +0 -55
- package/src/agent/subagents/static.js +0 -66
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dynamic-analysis
|
|
3
3
|
description: |
|
|
4
|
-
JS
|
|
5
|
-
|
|
4
|
+
JS 动态调试经验。请求追踪、调用栈分析、initiator、断点技巧、Hook 策略、反调试绕过。
|
|
5
|
+
触发:运行时调试、拦截加密调用、绕过反调试、请求追踪、调用栈、initiator。
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# 动态分析经验
|
|
9
9
|
|
|
10
10
|
## 定位技巧
|
|
11
11
|
|
|
12
|
-
**
|
|
13
|
-
1.
|
|
14
|
-
2.
|
|
15
|
-
3.
|
|
12
|
+
**Initiator 追溯法(最高效,首选):**
|
|
13
|
+
1. get_request_list 找到目标请求(注意 hasInitiator 标记)
|
|
14
|
+
2. get_request_initiator 获取调用栈
|
|
15
|
+
3. 调用栈直接指向发起请求的函数位置(脚本URL + 行号)
|
|
16
|
+
4. get_function_code 提取该函数及依赖
|
|
16
17
|
|
|
17
|
-
**
|
|
18
|
+
**XHR 断点法(Initiator 不可用时):**
|
|
19
|
+
1. set_xhr_breakpoint(urlPattern) — 设置 URL 关键词断点
|
|
20
|
+
2. 触发请求,断住后 get_call_stack
|
|
21
|
+
3. 从栈底向上找 encrypt/sign 相关函数
|
|
22
|
+
|
|
23
|
+
**Hook 观察法(需要持续监控时):**
|
|
18
24
|
1. 注入通用加密 Hook
|
|
19
25
|
2. 触发操作,观察日志
|
|
20
26
|
3. 根据日志定位具体函数
|
|
@@ -89,3 +95,64 @@ obj.func = function(...args) {
|
|
|
89
95
|
- 现象:页面变卡
|
|
90
96
|
- 原因:调用栈记录开销大
|
|
91
97
|
- 经验:关闭 `captureStack` 或启用 `silent` 模式
|
|
98
|
+
|
|
99
|
+
## 调试工作流模板
|
|
100
|
+
|
|
101
|
+
### 标准 XHR 断点工作流
|
|
102
|
+
1. set_xhr_breakpoint(urlPattern) — 设置 URL 关键词断点
|
|
103
|
+
2. 在页面触发目标请求
|
|
104
|
+
3. 断住后 get_call_stack() — 查看调用栈
|
|
105
|
+
4. 从栈底向上找 encrypt/sign/token 相关帧
|
|
106
|
+
5. get_frame_variables(frameIndex) — 查看关键帧的变量
|
|
107
|
+
6. evaluate_at_breakpoint('JSON.stringify(arguments)') — 获取函数入参
|
|
108
|
+
7. resume_execution() — 放行,观察下一次断住
|
|
109
|
+
|
|
110
|
+
### Cookie 生成追踪工作流
|
|
111
|
+
1. inject_hook('cookie') — 注入 Cookie Hook
|
|
112
|
+
2. 触发页面操作(登录/翻页)
|
|
113
|
+
3. get_hook_logs() — 查看 Cookie 写入日志
|
|
114
|
+
4. 从日志中找到目标 Cookie 的写入调用栈
|
|
115
|
+
5. 根据调用栈定位生成函数
|
|
116
|
+
6. set_breakpoint 在生成函数处断住,逐步分析
|
|
117
|
+
|
|
118
|
+
### 加密参数追踪工作流
|
|
119
|
+
1. analyze_request_params(site, id) — 识别可疑加密参数(hex/base64/hash)
|
|
120
|
+
2. search_in_scripts(site, paramName) — 搜索参数赋值位置
|
|
121
|
+
3. 如果搜不到(动态生成)→ set_xhr_breakpoint + 调用栈追踪
|
|
122
|
+
4. 定位到加密函数后 → get_function_code 提取完整代码
|
|
123
|
+
5. sandbox_execute 验证
|
|
124
|
+
|
|
125
|
+
## Hook 模板库
|
|
126
|
+
|
|
127
|
+
### Cookie 加密定位 Hook
|
|
128
|
+
```javascript
|
|
129
|
+
// 拦截 document.cookie 写入,记录调用栈
|
|
130
|
+
// 使用 inject_hook('cookie') 自动注入
|
|
131
|
+
// 日志格式:{ action: 'set', key, value, stack }
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### XMLHttpRequest 参数 Hook
|
|
135
|
+
```javascript
|
|
136
|
+
// 拦截 XHR open/send,记录请求参数
|
|
137
|
+
// 使用 inject_hook('xhr') 自动注入
|
|
138
|
+
// 日志格式:{ method, url, body, headers, stack }
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### CryptoJS 全量 Hook
|
|
142
|
+
```javascript
|
|
143
|
+
// 拦截 CryptoJS 所有加密/解密调用
|
|
144
|
+
// 使用 generate_cryptojs_hook() 生成
|
|
145
|
+
// 日志格式:{ algorithm, mode, input, key, iv, output, stack }
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### 自定义函数 Hook 模式
|
|
149
|
+
```javascript
|
|
150
|
+
// 当标准 Hook 未捕获到加密调用时:
|
|
151
|
+
// 1. 通过静态分析找到可疑函数名
|
|
152
|
+
// 2. evaluate_at_breakpoint 注入针对性 Hook:
|
|
153
|
+
// const _orig = window.targetFunc;
|
|
154
|
+
// window.targetFunc = function(...args) {
|
|
155
|
+
// console.log('[Hook]', args, new Error().stack);
|
|
156
|
+
// return _orig.apply(this, args);
|
|
157
|
+
// };
|
|
158
|
+
```
|
|
@@ -70,3 +70,78 @@ var document = {
|
|
|
70
70
|
| headless | `navigator.plugins.length` |
|
|
71
71
|
| canvas | `toDataURL()` |
|
|
72
72
|
| WebGL | `getParameter()` |
|
|
73
|
+
|
|
74
|
+
## 完整环境补丁模板
|
|
75
|
+
|
|
76
|
+
### navigator 完整补丁
|
|
77
|
+
```javascript
|
|
78
|
+
var navigator = {
|
|
79
|
+
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
|
|
80
|
+
appVersion: '5.0 (Windows NT 10.0; Win64; x64)',
|
|
81
|
+
platform: 'Win32',
|
|
82
|
+
language: 'zh-CN',
|
|
83
|
+
languages: ['zh-CN', 'zh'],
|
|
84
|
+
cookieEnabled: true,
|
|
85
|
+
webdriver: undefined,
|
|
86
|
+
plugins: { length: 3, 0: {name: 'Chrome PDF Plugin'}, 1: {name: 'Chrome PDF Viewer'}, 2: {name: 'Native Client'} },
|
|
87
|
+
mimeTypes: { length: 4 },
|
|
88
|
+
hardwareConcurrency: 8,
|
|
89
|
+
maxTouchPoints: 0,
|
|
90
|
+
vendor: 'Google Inc.',
|
|
91
|
+
productSub: '20030107',
|
|
92
|
+
};
|
|
93
|
+
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### localStorage / sessionStorage 补丁
|
|
97
|
+
```javascript
|
|
98
|
+
class FakeStorage {
|
|
99
|
+
constructor() { this._data = {}; }
|
|
100
|
+
getItem(k) { return this._data[k] ?? null; }
|
|
101
|
+
setItem(k, v) { this._data[k] = String(v); }
|
|
102
|
+
removeItem(k) { delete this._data[k]; }
|
|
103
|
+
clear() { this._data = {}; }
|
|
104
|
+
get length() { return Object.keys(this._data).length; }
|
|
105
|
+
key(i) { return Object.keys(this._data)[i] ?? null; }
|
|
106
|
+
}
|
|
107
|
+
var localStorage = new FakeStorage();
|
|
108
|
+
var sessionStorage = new FakeStorage();
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### XMLHttpRequest 补丁
|
|
112
|
+
```javascript
|
|
113
|
+
class XMLHttpRequest {
|
|
114
|
+
constructor() { this.readyState = 0; this.status = 0; this.responseText = ''; }
|
|
115
|
+
open(method, url) { this._method = method; this._url = url; this.readyState = 1; }
|
|
116
|
+
send(body) { this.readyState = 4; this.status = 200; if (this.onreadystatechange) this.onreadystatechange(); }
|
|
117
|
+
setRequestHeader() {}
|
|
118
|
+
getResponseHeader() { return null; }
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Canvas / WebGL 指纹补丁
|
|
123
|
+
```javascript
|
|
124
|
+
// Canvas
|
|
125
|
+
var HTMLCanvasElement = function() {};
|
|
126
|
+
HTMLCanvasElement.prototype.getContext = function(type) {
|
|
127
|
+
if (type === '2d') return {
|
|
128
|
+
fillRect: () => {}, fillText: () => {}, measureText: () => ({width: 0}),
|
|
129
|
+
getImageData: () => ({data: new Uint8Array(0)}),
|
|
130
|
+
};
|
|
131
|
+
return null;
|
|
132
|
+
};
|
|
133
|
+
HTMLCanvasElement.prototype.toDataURL = () => 'data:image/png;base64,iVBOR...';
|
|
134
|
+
|
|
135
|
+
// WebGL
|
|
136
|
+
var WebGLRenderingContext = function() {};
|
|
137
|
+
WebGLRenderingContext.prototype.getParameter = function(p) {
|
|
138
|
+
const map = { 7937: 'WebKit WebGL', 7936: 'WebKit', 37445: 'Google Inc.', 37446: 'ANGLE' };
|
|
139
|
+
return map[p] || 0;
|
|
140
|
+
};
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### 补环境调试策略
|
|
144
|
+
1. 先跑一遍,收集所有 `xxx is not defined` 错误
|
|
145
|
+
2. 按错误顺序逐个补丁(window → document → navigator → ...)
|
|
146
|
+
3. 每补一个重新跑,直到无报错
|
|
147
|
+
4. 对比浏览器输出验证结果一致性
|
|
@@ -20,3 +20,38 @@ description: |
|
|
|
20
20
|
## 验证技巧
|
|
21
21
|
|
|
22
22
|
用浏览器控制台的输入输出作为测试用例,对比沙箱执行结果。
|
|
23
|
+
|
|
24
|
+
## 分层验证策略
|
|
25
|
+
|
|
26
|
+
### 第一层:函数级验证
|
|
27
|
+
```
|
|
28
|
+
1. get_function_code 提取目标函数(含依赖)
|
|
29
|
+
2. sandbox_execute 直接运行
|
|
30
|
+
3. 对比浏览器控制台的输出
|
|
31
|
+
```
|
|
32
|
+
如果报错 `xxx is not defined` → 进入第二层
|
|
33
|
+
|
|
34
|
+
### 第二层:补环境验证
|
|
35
|
+
```
|
|
36
|
+
1. 收集报错中缺失的变量名
|
|
37
|
+
2. 用 collect_env / collect_property 从浏览器采集真实值
|
|
38
|
+
3. generate_patch 生成补丁
|
|
39
|
+
4. sandbox_inject(补丁) + sandbox_execute(函数)
|
|
40
|
+
5. 对比结果
|
|
41
|
+
```
|
|
42
|
+
如果结果不一致 → 进入第三层
|
|
43
|
+
|
|
44
|
+
### 第三层:完整环境验证
|
|
45
|
+
```
|
|
46
|
+
1. generate_env_dump_code 生成全量环境自吐
|
|
47
|
+
2. 在浏览器执行,收集完整环境
|
|
48
|
+
3. load_all_env_modules 加载全部补丁
|
|
49
|
+
4. sandbox_inject + sandbox_execute
|
|
50
|
+
5. 如果仍不一致 → 检查是否有反调试/时间检测
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 验证对比技巧
|
|
54
|
+
- 哈希值:直接字符串比较
|
|
55
|
+
- 加密结果:如果有 IV/随机数,固定后再比较
|
|
56
|
+
- 时间戳相关:Hook Date.now() 返回固定值
|
|
57
|
+
- 多次执行:确认结果稳定性(排除随机因素)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: static-analysis
|
|
3
3
|
description: |
|
|
4
|
-
JS
|
|
5
|
-
|
|
4
|
+
JS 静态代码分析经验。混淆识别、加密定位、代码还原、CSS/字体反爬。
|
|
5
|
+
触发:分析混淆代码、定位加密函数、还原算法逻辑、CSS反爬、字体反爬、伪元素反爬、SVG反爬。
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# 静态分析经验
|
|
@@ -211,3 +211,99 @@ C1C2C3 格式 (旧):
|
|
|
211
211
|
- ey开头 → JWT
|
|
212
212
|
- -----BEGIN → PEM格式密钥
|
|
213
213
|
```
|
|
214
|
+
|
|
215
|
+
## CSS/字体反爬(数据混淆还原)
|
|
216
|
+
|
|
217
|
+
### 字体反爬(font-face)
|
|
218
|
+
**特征**:页面数字/文字显示正常,但复制出来是乱码或错误字符。
|
|
219
|
+
**原理**:自定义 @font-face 将 Unicode 码点映射到不同字形。
|
|
220
|
+
**破解思路**:
|
|
221
|
+
1. 找到 @font-face 的 woff/ttf 文件 URL
|
|
222
|
+
2. 下载字体文件,解析 cmap 表获取映射关系
|
|
223
|
+
3. 建立 显示字符 → 真实字符 的映射表
|
|
224
|
+
4. 替换页面文本
|
|
225
|
+
|
|
226
|
+
**识别关键词**:`@font-face`、`font-family` 自定义名称、`.woff`、`.ttf`
|
|
227
|
+
|
|
228
|
+
### CSS 偏移反爬
|
|
229
|
+
**特征**:HTML 中数字顺序与显示不同,通过 CSS position/left/transform 重排。
|
|
230
|
+
**原理**:每个数字用 span 包裹,通过 CSS 偏移到正确位置。
|
|
231
|
+
**破解思路**:
|
|
232
|
+
1. 获取每个 span 的 computed style(left/transform 值)
|
|
233
|
+
2. 按偏移量排序还原真实顺序
|
|
234
|
+
3. 或直接用 element.innerText 获取渲染后文本
|
|
235
|
+
|
|
236
|
+
**识别关键词**:`position: absolute`、`left: -Npx`、`transform: translateX`
|
|
237
|
+
|
|
238
|
+
### 伪元素反爬(::before/::after)
|
|
239
|
+
**特征**:页面有内容但 DOM 中对应元素为空。
|
|
240
|
+
**原理**:通过 CSS `content` 属性在伪元素中插入文本。
|
|
241
|
+
**破解思路**:
|
|
242
|
+
1. `getComputedStyle(el, '::before').content` 获取伪元素内容
|
|
243
|
+
2. 或解析 CSS 样式表中的 content 规则
|
|
244
|
+
|
|
245
|
+
**识别关键词**:`::before`、`::after`、`content:`
|
|
246
|
+
|
|
247
|
+
### SVG 路径反爬
|
|
248
|
+
**特征**:数字是 SVG 图形而非文本。
|
|
249
|
+
**原理**:用 SVG path 绘制数字,无法直接提取文本。
|
|
250
|
+
**破解思路**:
|
|
251
|
+
1. 提取 SVG viewBox 和 path d 属性
|
|
252
|
+
2. 对比已知数字的 path 特征(模板匹配)
|
|
253
|
+
3. 或 OCR 识别截图
|
|
254
|
+
|
|
255
|
+
### 背景图片反爬
|
|
256
|
+
**特征**:数字通过 background-image + background-position 显示。
|
|
257
|
+
**原理**:一张雪碧图包含所有数字,通过偏移显示特定数字。
|
|
258
|
+
**破解思路**:
|
|
259
|
+
1. 下载雪碧图
|
|
260
|
+
2. 根据 background-position 计算显示的是哪个数字
|
|
261
|
+
3. 建立 position → 数字 的映射
|
|
262
|
+
|
|
263
|
+
### 快速判断流程
|
|
264
|
+
|
|
265
|
+
```
|
|
266
|
+
页面数字复制异常?
|
|
267
|
+
├── 复制出乱码 → 字体反爬(检查 @font-face)
|
|
268
|
+
├── 复制出错误顺序 → CSS 偏移(检查 position/transform)
|
|
269
|
+
├── 复制为空 → 伪元素(检查 ::before/::after)或 SVG/Canvas
|
|
270
|
+
└── 复制正常但值不对 → JS 动态渲染(检查 MutationObserver)
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## 加密链路追踪
|
|
274
|
+
|
|
275
|
+
### 追踪方法论
|
|
276
|
+
从请求参数出发,逆向追踪到加密函数:
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
请求参数 sign=xxx
|
|
280
|
+
→ analyze_correlation 找到参数来源
|
|
281
|
+
→ search_in_scripts 搜索赋值位置
|
|
282
|
+
→ get_function_code 提取加密函数(含依赖)
|
|
283
|
+
→ 分析函数内部:识别算法 + 找到 key/iv 来源
|
|
284
|
+
→ 如果 key 是动态的 → 继续追踪 key 的生成逻辑
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### 多层加密识别
|
|
288
|
+
常见模式:外层签名 + 内层加密
|
|
289
|
+
```
|
|
290
|
+
sign = MD5(timestamp + token + data)
|
|
291
|
+
其中 token = AES(userId, serverKey)
|
|
292
|
+
其中 serverKey = RSA_decrypt(encryptedKey, privateKey)
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**识别技巧**:
|
|
296
|
+
- 一个函数的输出是另一个函数的输入 → 链式加密
|
|
297
|
+
- 同一个请求有多个加密参数 → 可能共享中间值
|
|
298
|
+
- 参数名含 `sign`/`token`/`ticket` → 通常是最外层
|
|
299
|
+
|
|
300
|
+
### 参数来源分类
|
|
301
|
+
|
|
302
|
+
| 来源 | 特征 | 追踪方式 |
|
|
303
|
+
|------|------|----------|
|
|
304
|
+
| 硬编码 | 代码中直接赋值 | 静态搜索 |
|
|
305
|
+
| 服务端下发 | 从接口响应中提取 | search_in_responses |
|
|
306
|
+
| 页面元素 | 从 DOM 中读取 | 搜索 getElementById/querySelector |
|
|
307
|
+
| Cookie | document.cookie | Cookie Hook |
|
|
308
|
+
| 时间戳 | Date.now() / new Date() | 固定值即可 |
|
|
309
|
+
| 随机数 | Math.random() | 固定值即可 |
|
|
@@ -3,19 +3,17 @@
|
|
|
3
3
|
* 浏览器指纹管理、代理池、风控规避
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
import { SKILLS, skillsBackend } from '../skills/config.js';
|
|
8
|
-
import { createFilterToolsMiddleware } from '../middleware/filterTools.js';
|
|
6
|
+
import { createSubagent } from './factory.js';
|
|
9
7
|
|
|
10
8
|
import { antiDetectTools } from '../tools/index.js';
|
|
11
9
|
import { browserTools } from '../tools/browser.js';
|
|
10
|
+
import { profileTools } from '../tools/profile.js';
|
|
12
11
|
import { fileTools } from '../tools/file.js';
|
|
13
|
-
import { evolveTools } from '../tools/evolve.js';
|
|
14
12
|
|
|
15
|
-
export const antiDetectSubagent = {
|
|
13
|
+
export const antiDetectSubagent = createSubagent({
|
|
16
14
|
name: 'anti-detect',
|
|
17
|
-
description: '
|
|
18
|
-
systemPrompt: `你是 DeepSpider
|
|
15
|
+
description: '反检测专家。适用于:代理 IP 配置与轮换、浏览器指纹伪装、请求特征修改、风控规避策略。不能做加密分析、不能反混淆、不能处理验证码。',
|
|
16
|
+
systemPrompt: `你是 DeepSpider 的反检测专家,负责绕过网站的反爬虫检测。
|
|
19
17
|
|
|
20
18
|
## 核心职责
|
|
21
19
|
配置反检测环境,规避风控系统,确保爬虫稳定运行。
|
|
@@ -25,21 +23,13 @@ export const antiDetectSubagent = {
|
|
|
25
23
|
- 浏览器指纹:指纹伪装
|
|
26
24
|
- 行为检测:模拟人类操作
|
|
27
25
|
- TLS 指纹:使用真实浏览器
|
|
28
|
-
|
|
29
|
-
## 经验记录
|
|
30
|
-
完成反检测配置后,如发现有价值的经验,使用 evolve_skill 记录:
|
|
31
|
-
- skill: "anti-detect"`,
|
|
26
|
+
`,
|
|
32
27
|
tools: [
|
|
33
28
|
...antiDetectTools,
|
|
34
29
|
...browserTools,
|
|
30
|
+
...profileTools,
|
|
35
31
|
...fileTools,
|
|
36
|
-
...evolveTools,
|
|
37
|
-
],
|
|
38
|
-
middleware: [
|
|
39
|
-
createFilterToolsMiddleware(),
|
|
40
|
-
createSkillsMiddleware({
|
|
41
|
-
backend: skillsBackend,
|
|
42
|
-
sources: [SKILLS.antiDetect],
|
|
43
|
-
}),
|
|
44
32
|
],
|
|
45
|
-
|
|
33
|
+
skills: ['antiDetect'],
|
|
34
|
+
evolveSkill: 'anti-detect',
|
|
35
|
+
});
|
|
@@ -3,18 +3,15 @@
|
|
|
3
3
|
* 识别和绕过各类验证码
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
import { SKILLS, skillsBackend } from '../skills/config.js';
|
|
8
|
-
import { createFilterToolsMiddleware } from '../middleware/filterTools.js';
|
|
6
|
+
import { createSubagent } from './factory.js';
|
|
9
7
|
|
|
10
8
|
import { captchaTools } from '../tools/captcha.js';
|
|
11
9
|
import { browserTools } from '../tools/browser.js';
|
|
12
10
|
import { fileTools } from '../tools/file.js';
|
|
13
|
-
import { evolveTools } from '../tools/evolve.js';
|
|
14
11
|
|
|
15
|
-
export const captchaSubagent = {
|
|
12
|
+
export const captchaSubagent = createSubagent({
|
|
16
13
|
name: 'captcha',
|
|
17
|
-
description: '
|
|
14
|
+
description: '验证码处理专家。适用于:图片验证码 OCR、滑块验证码缺口检测与轨迹模拟、点选验证码目标检测。不能做加密分析、不能反混淆、不能生成爬虫脚本。',
|
|
18
15
|
systemPrompt: `你是 DeepSpider 的验证码处理专家,负责识别和绕过各类验证码。
|
|
19
16
|
|
|
20
17
|
## 核心职责
|
|
@@ -31,21 +28,12 @@ export const captchaSubagent = {
|
|
|
31
28
|
2. 选择处理策略
|
|
32
29
|
3. 执行验证
|
|
33
30
|
4. 检查结果,失败则重试
|
|
34
|
-
|
|
35
|
-
## 经验记录
|
|
36
|
-
完成验证码处理后,如发现有价值的经验,使用 evolve_skill 记录:
|
|
37
|
-
- skill: "captcha"`,
|
|
31
|
+
`,
|
|
38
32
|
tools: [
|
|
39
33
|
...captchaTools,
|
|
40
34
|
...browserTools,
|
|
41
35
|
...fileTools,
|
|
42
|
-
...evolveTools,
|
|
43
|
-
],
|
|
44
|
-
middleware: [
|
|
45
|
-
createFilterToolsMiddleware(),
|
|
46
|
-
createSkillsMiddleware({
|
|
47
|
-
backend: skillsBackend,
|
|
48
|
-
sources: [SKILLS.captcha],
|
|
49
|
-
}),
|
|
50
36
|
],
|
|
51
|
-
|
|
37
|
+
skills: ['captcha'],
|
|
38
|
+
evolveSkill: 'captcha',
|
|
39
|
+
});
|
|
@@ -3,28 +3,24 @@
|
|
|
3
3
|
* 智能调度、流程规划、脚本生成
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
import { SKILLS, skillsBackend } from '../skills/config.js';
|
|
8
|
-
import { createFilterToolsMiddleware } from '../middleware/filterTools.js';
|
|
6
|
+
import { createSubagent } from './factory.js';
|
|
9
7
|
|
|
10
8
|
import { crawlerTools } from '../tools/crawler.js';
|
|
11
9
|
import { fileTools } from '../tools/file.js';
|
|
12
|
-
import { evolveTools } from '../tools/evolve.js';
|
|
13
10
|
import { storeTools } from '../tools/store.js';
|
|
11
|
+
import { getPageSource, getElementHtml } from '../tools/browser.js';
|
|
14
12
|
|
|
15
|
-
export const crawlerSubagent = {
|
|
13
|
+
export const crawlerSubagent = createSubagent({
|
|
16
14
|
name: 'crawler',
|
|
17
|
-
description: '
|
|
15
|
+
description: '爬虫编排专家。适用于:规划完整爬虫流程、整合各模块生成完整 Python 爬虫脚本。不能做加密分析、不能反混淆、不能控制浏览器。依赖其他子代理提供加密/验证码等模块。',
|
|
18
16
|
systemPrompt: `你是 DeepSpider 的爬虫编排专家,负责生成完整可运行的 Python 爬虫脚本。
|
|
19
17
|
|
|
20
18
|
## 核心职责
|
|
21
19
|
**最终目标:输出一份用户可以直接 python crawler.py 运行的完整爬虫代码**
|
|
22
20
|
|
|
23
|
-
1.
|
|
24
|
-
2.
|
|
25
|
-
3.
|
|
26
|
-
4. E2E 测试验证脚本可运行
|
|
27
|
-
5. 输出最终代码文件
|
|
21
|
+
1. 根据主 agent 提供的分析结果和已验证的代码模块,整合生成完整 Python 爬虫脚本
|
|
22
|
+
2. 使用 artifact_save 保存代码文件
|
|
23
|
+
3. 输出最终代码文件路径
|
|
28
24
|
|
|
29
25
|
## 网站复杂度分级
|
|
30
26
|
|
|
@@ -46,16 +42,15 @@ export const crawlerSubagent = {
|
|
|
46
42
|
- 设备指纹检测
|
|
47
43
|
- 行为分析
|
|
48
44
|
|
|
49
|
-
##
|
|
45
|
+
## 输入来源
|
|
50
46
|
|
|
51
|
-
|
|
47
|
+
主 agent 会在 task description 中提供:
|
|
48
|
+
- 接口分析结果(URL、方法、参数、Headers)
|
|
49
|
+
- 已验证的加密代码文件路径(如有)
|
|
50
|
+
- 用户选择的框架(requests / scrapy / playwright 等)
|
|
52
51
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
| 有加密参数 | static → js2python | crypto.py |
|
|
56
|
-
| 有验证码 | captcha 分析 | 生成验证码处理代码 |
|
|
57
|
-
| 有风控 | anti-detect 分析 | 生成反检测配置代码 |
|
|
58
|
-
| 需要登录 | dynamic 分析 | 生成登录流程代码 |
|
|
52
|
+
你的任务是基于这些信息整合生成完整爬虫脚本,不需要自己分析加密或调度其他子代理。
|
|
53
|
+
如需查看已有的加密代码,用 \`query_store\` 或 \`artifact_load\` 读取。
|
|
59
54
|
|
|
60
55
|
## 输出规范
|
|
61
56
|
|
|
@@ -113,26 +108,19 @@ if __name__ == "__main__":
|
|
|
113
108
|
\`\`\`
|
|
114
109
|
|
|
115
110
|
## 工作流程
|
|
116
|
-
1.
|
|
117
|
-
2.
|
|
118
|
-
3.
|
|
119
|
-
4.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
## 经验记录
|
|
123
|
-
完成爬虫编排后,如发现有价值的经验,使用 evolve_skill 记录:
|
|
124
|
-
- skill: "crawler"`,
|
|
111
|
+
1. 读取主 agent 提供的分析结果和已有代码模块(query_store / artifact_load)
|
|
112
|
+
2. 整合为完整可运行的 Python 爬虫脚本
|
|
113
|
+
3. 使用 artifact_save 保存文件
|
|
114
|
+
4. 输出文件路径
|
|
115
|
+
`,
|
|
125
116
|
tools: [
|
|
126
117
|
...crawlerTools,
|
|
127
118
|
...fileTools,
|
|
128
|
-
...evolveTools,
|
|
129
119
|
...storeTools,
|
|
120
|
+
// 页面结构分析(主 agent 不持有,防止拉 HTML 自己分析 JS)
|
|
121
|
+
getPageSource,
|
|
122
|
+
getElementHtml,
|
|
130
123
|
],
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
backend: skillsBackend,
|
|
135
|
-
sources: [SKILLS.crawler, SKILLS.xpath],
|
|
136
|
-
}),
|
|
137
|
-
],
|
|
138
|
-
};
|
|
124
|
+
skills: ['crawler', 'xpath'],
|
|
125
|
+
evolveSkill: 'crawler',
|
|
126
|
+
});
|