feat(v2.3.0): fetch 结构化 JSON 契约 + 并发批量 + 真实并发门控
迭代 1 — 正确性修复:
- 修复 --pages N 多页聚合的 unresponsive-engine 警告误判: 原用循环末次
cached 变量判断, 缓存命中时警告被错误跳过/误触发; 改用独立
performed_live_query 标记
- UA 池单一来源: 删除 common.py 手工副本 _FALLBACK_UAS_BUILTIN,
FALLBACK_UAS 直接引用 _config.UA_POOL, 消除双份漂移
- search_html 解码修复: 硬编码 utf-8 改为 detect_charset(header/meta
自动检测), 新增 --encoding 强制覆盖, 贯穿 search_multi 全链
- AdaptiveThrottle 真实并发门控: acquire_slot()/release_slot() 槽位机制,
退避降并发后新请求被快速拒绝(E_RATE_LIMIT), 实现持久降并发而非名义降并发
迭代 2 — fetch JSON 契约 + 批量并发:
- fetch.py --format json: 成功 {status,url,final_url,content_type,extract,
truncated,text_length,user_agent}; 失败 {status,error,error_code,
status_code,url}, 对齐 search.py 错误码体系
- fetch_page 采集 title + latency, 填充 --fetch-report json 空字段
- --queries-file --parallel-queries N (1-8): 并发批量, 输出保序, 受
AdaptiveThrottle 门控; 并发模式禁用 --fetch(嵌套并行不安全)
- queries 文件编码自动检测 (UTF-8 → GBK 回退)
迭代 3 — 工程化:
- 新增 pyproject.toml (searxng-search/searxng-fetch 入口点)
- 收敛 20+ 处函数内冗余导入
- --dump-schema 扩展: fetched.items 补全 15 字段, 新增 defs.batch/research
- 新增 17 个测试 (tests/test_v230_features.py), 全量 561 测试通过
- 文档同步 (SKILL.md/README.md, 版本号 2.3.0)
This commit is contained in:
@@ -206,6 +206,7 @@ python scripts/search.py -q "查询词" -i https://your-instance \
|
||||
| `--request-delay` | v2.0.0 抓取请求间隔秒数(自适应限流可能增大) | 0.3 |
|
||||
| `--cache-ttl` | 缓存分钟数 | 0(不缓存) |
|
||||
| `--queries-file` | 批量查询文件(每行一个查询) | — |
|
||||
| `--parallel-queries` | v2.3.0 并发批量查询 worker 数(1-8,输出保序,受自适应限流门控;并发时禁用 --fetch) | 0(串行) |
|
||||
| `--research` | v2.1.0 研究模式:给定主题自动扩展 5 个多角度查询 | — |
|
||||
| `--include-domain` | 域名白名单 | — |
|
||||
| `--exclude-domain` | 域名黑名单 | — |
|
||||
@@ -236,6 +237,7 @@ python scripts/search.py -q "查询词" -i https://your-instance \
|
||||
```bash
|
||||
python scripts/fetch.py -u https://example.com \
|
||||
--extract text|html|markdown \
|
||||
--format text|json \ # v2.3.0: json = 结构化 JSON 契约
|
||||
[--encoding gbk] \
|
||||
[--max-size 5242880] \
|
||||
[--timeout 15] \
|
||||
@@ -249,6 +251,7 @@ python scripts/fetch.py -u https://example.com \
|
||||
| 参数 | 说明 | 默认值 |
|
||||
|------|------|--------|
|
||||
| `-u / --url` | 目标 URL(必填) | — |
|
||||
| `-f / --format` | v2.3.0 输出格式:text/json(json = 结构化 JSON 契约,成功 `{status,url,final_url,content_type,extract,truncated,text_length,user_agent}`,失败 `{status,error,error_code,status_code,url}`) | text |
|
||||
| `-e / --extract` | 提取模式:text/html/markdown | text |
|
||||
| `--encoding` | 强制字符编码 | 自动检测 |
|
||||
| `--max-size` | 最大字节数 | 不限 |
|
||||
@@ -263,6 +266,17 @@ python scripts/fetch.py -u https://example.com \
|
||||
|
||||
## 能力清单
|
||||
|
||||
**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 回退)
|
||||
- 真实并发门控:`AdaptiveThrottle.acquire_slot()/release_slot()`——退避降并发后新请求被快速拒绝(返回 `E_RATE_LIMIT`),实现持久降并发(原实现仅名义降并发,线程池规模固定)
|
||||
- `--fetch-report json` 字段补齐:`fetch_page` 采集 `title`(页面标题)与 `latency`(耗时秒数),此前恒为 None
|
||||
- `--dump-schema` 扩展:`fetched.items` 字段补全(final_url/status/error_code/waf_type/fallback_used/title/latency 等),新增 `defs.batch`/`defs.research` 描述批量与研究模式输出 shape
|
||||
- 修复多页聚合(`--pages N`)的 unresponsive-engine 警告误判:原实现用循环末次 `cached` 变量判断,缓存命中时警告被错误跳过/误触发;现用独立 `performed_live_query` 标记
|
||||
- UA 池单一来源:删除 common.py 的手工副本 `_FALLBACK_UAS_BUILTIN`,`FALLBACK_UAS` 直接引用 `_config.UA_POOL`(消除双份漂移风险)
|
||||
- search_html 解码修复:改用 `detect_charset`(header/meta 自动检测),新增 `--encoding` 强制覆盖(非 UTF-8 SearXNG 实例不再乱码)
|
||||
- 新增 `pyproject.toml`(可选打包,`searxng-search`/`searxng-fetch` 入口点);函数内冗余导入收敛
|
||||
|
||||
**v2.2.1 修复**
|
||||
- Brotli 乱码修复:`build_browser_headers()` 智能声明 `Accept-Encoding`——仅当本机安装了 brotli/brotlicffi 包时才声明 `br`,避免服务器返回 Brotli 压缩字节而 requests 无法自动解压导致全页乱码
|
||||
- `fetch.py` 双路径 br 解压:requests 路径和 stdlib urllib 路径都添加了 Brotli 手动解压逻辑(作为双保险,应对代理/CDN 强制返回 br 的边缘情况)
|
||||
@@ -351,7 +365,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` 字段区分成功/失败)
|
||||
- 544 个单元+集成测试
|
||||
- 561 个单元+集成测试
|
||||
|
||||
## 跨 Agent 兼容性
|
||||
|
||||
@@ -379,7 +393,7 @@ pip install pytest
|
||||
pytest -q
|
||||
```
|
||||
|
||||
539 个测试覆盖:缓存操作、认证解析、域名过滤、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)。
|
||||
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 并发批量)。
|
||||
|
||||
## 项目结构
|
||||
|
||||
|
||||
Reference in New Issue
Block a user