feat(v2.4.0): 新增 E_BLOCKED 错误码——细分 fetch 403 反爬拦截

真实环境问题: 抓取被墙/反爬站点 (如 baike.baidu.com) 返回 403 时,
classify_error 统一归为 E_AUTH, AI Agent 会误判为凭证问题而做无效的
认证重试。被封锁不是认证失败。

改动:
- common.py: 新增 E_BLOCKED 错误码 + recovery_hint (提示换 URL/镜像/
  用 Wayback 兜底/--exclude-domain); 新增 classify_fetch_error() 与
  _extract_status_code(): fetch 场景 403→E_BLOCKED, 401→E_AUTH,
  其余委托 classify_error (搜索场景 403 仍为 E_AUTH, 不变)
- fetch.py main(): 错误路径改用 classify_fetch_error (替代 classify_error)
- search.py: fetch_page 与 fetch_top_results 线程错误路径同样切换
- 新增 11 个测试 (test_v240_blocked_code.py), 全量 572 测试通过
- 真实环境验证: baike 403 → E_BLOCKED, 正常站点不受影响
- 文档同步 (SKILL.md/README.md 错误码表, 版本号 2.4.0)
This commit is contained in:
2026-08-05 20:24:25 +08:00
parent 4df521dc9d
commit 471818074d
7 changed files with 177 additions and 9 deletions
+7 -2
View File
@@ -63,12 +63,14 @@ AI 调用后,stdout 输出网页正文(text/html/markdown 三种格式),
|--------|------|----------------------|
| `E_CONFIG` | 配置错误(无实例) | 设置 `-i`/`SEARXNG_INSTANCE`/配置文件 |
| `E_AUTH` | 认证失败(401/403) | 检查凭证、token 过期与权限 |
| `E_BLOCKED` | 抓取被站点反爬/WAF 拦截(403,v2.4.0 | 不是凭证问题——用 Wayback 兜底(默认开)、换镜像/其他 URL、或 `--exclude-domain` 排除该域名 |
| `E_NETWORK` | 网络错误(连接失败、5xx) | 重试退避、切换实例、检查代理 |
| `E_RATE_LIMIT` | 限流(429) | 等待重试、降低频率、分散负载 |
| `E_PARSE` | 解析错误 | 切换实例、切换 `--method` |
| `E_EMPTY` | 空结果(exit 2) | 调整查询词、扩大 `--time-range`/`--categories` |
| `E_INPUT` | 输入错误(参数/文件) | 检查语法、标志组合、文件路径 |
| `E_INTERNAL` | 内部错误 | 用 `--verbose` 重跑并报告 |
| `E_BLOCKED` (v2.4.0) | 抓取被反爬/WAF 拦截(403) | 换 URL/镜像,或 `--exclude-domain`Wayback 兜底默认开启 |
| `E_UNSUPPORTED_MEDIA` (v2.2.0) | 不支持的二进制媒体类型(PDF/docx/xlsx 解析失败) | 换 URL,或安装 `pdftotext` 用于 PDF 解析 |
### 流式输出与进度事件(AI 高级用法)
@@ -266,6 +268,9 @@ python scripts/fetch.py -u https://example.com \
## 能力清单
**v2.4.0 新功能**
- 新增 `E_BLOCKED` 错误码:fetch 场景的 403(WAF/反爬拦截)从 `E_AUTH` 细分出来——被封锁不是凭证问题,AI Agent 不再误判为"需要检查认证"。新增 `classify_fetch_error()` / `_extract_status_code()`common.py),应用于 `fetch.py``search.py --fetch`SearXNG 实例认证的 403 仍映射 `E_AUTH`(搜索场景不变)
**v2.3.0 新功能与修复**
- `fetch.py --format json`:结构化 JSON 输出契约。成功 `{status, url, final_url, content_type, extract, truncated, text_length, user_agent}`;失败 `{status, error, error_code, status_code, url}`(对齐 search.py 错误码体系,含 `E_UNSUPPORTED_MEDIA`)。AI Agent 可程序化解析抓取结果,无需再解析裸文本
- `--parallel-queries N`:批量模式并发执行(1-8 workers,输出保持文件顺序),受 AdaptiveThrottle 真实并发门控约束;并发模式下禁用 `--fetch`(嵌套并行抓取不安全)。queries 文件编码自动检测(UTF-8 → GBK 回退)
@@ -365,7 +370,7 @@ python scripts/fetch.py -u https://example.com \
- JSON Lines 流式输出(`--stream`,含 `error` 事件类型)
- 进度事件(`--progress`,含 `instance_try`/`instance_ok`/`instance_fail`JSON Lines 到 stderr
- batch 模式统一 schema`status` 字段区分成功/失败)
- 561 个单元+集成测试
- 572 个单元+集成测试
## 跨 Agent 兼容性
@@ -393,7 +398,7 @@ pip install pytest
pytest -q
```
561 个测试覆盖:缓存操作、认证解析、域名过滤、Markdown 转换、搜索逻辑、集成流程、日志配置、HTML 回退、自动抓取、健康检查、输出格式化、实例解析、并行搜索、CLI 端到端、错误码分类、流式输出、进度事件、配置文件认证、schema_version、recovery_hint、batch 统一 schema、--dump-schema、UTF-8 stdout 强制、Windows APPDATA 路径、v2.0.0 浏览器指纹头、WAF 反爬检测(v2.0.1 收窄误判 + title 精准检测)、Wayback Machine 兜底(v2.0.1 修复 HTTP 200 反爬页触发)、自适应限流(v2.1.1 结构化 error_code 检测 429)、v2.1.0 Wayback 共享逻辑(should_try_wayback/build_wayback_url)、被墙站点智能回退(v2.1.1 精确化 baidu 子域,pan/cloud 不再误伤)、--research 研究模式(v2.1.1 跨角度合并去重 + 中英文双语后缀)、--time-range week 支持(v2.1.1)、stdlib gzip/deflate 解压(v2.1.1)、实例引擎挂起检测(v2.1.1 _warn_unresponsive_engines)、v2.3.0 新功能(多页实时查询跟踪、GBK charset 检测与 --encoding、UA 单源、并发槽位门控、fetch JSON 契约、fetch_page title/latency、GBK queries 文件、--parallel-queries 并发批量)。
572 个测试覆盖:缓存操作、认证解析、域名过滤、Markdown 转换、搜索逻辑、集成流程、日志配置、HTML 回退、自动抓取、健康检查、输出格式化、实例解析、并行搜索、CLI 端到端、错误码分类、流式输出、进度事件、配置文件认证、schema_version、recovery_hint、batch 统一 schema、--dump-schema、UTF-8 stdout 强制、Windows APPDATA 路径、v2.0.0 浏览器指纹头、WAF 反爬检测(v2.0.1 收窄误判 + title 精准检测)、Wayback Machine 兜底(v2.0.1 修复 HTTP 200 反爬页触发)、自适应限流(v2.1.1 结构化 error_code 检测 429)、v2.1.0 Wayback 共享逻辑(should_try_wayback/build_wayback_url)、被墙站点智能回退(v2.1.1 精确化 baidu 子域,pan/cloud 不再误伤)、--research 研究模式(v2.1.1 跨角度合并去重 + 中英文双语后缀)、--time-range week 支持(v2.1.1)、stdlib gzip/deflate 解压(v2.1.1)、实例引擎挂起检测(v2.1.1 _warn_unresponsive_engines)、v2.3.0 新功能(多页实时查询跟踪、GBK charset 检测与 --encoding、UA 单源、并发槽位门控、fetch JSON 契约、fetch_page title/latency、GBK queries 文件、--parallel-queries 并发批量)、v2.4.0 E_BLOCKED 错误码(fetch 403 反爬拦截细分,classify_fetch_error
## 项目结构