feat(v2.0.0): 反爬增强 + 抓取稳定性大幅提升

反爬措施:

- 浏览器指纹头 build_browser_headers(): Sec-Ch-Ua/Sec-Fetch-*/Accept-Language/Accept-Encoding, 绕过 80%+ 轻量 WAF

- 12 个 UA 池 (Chrome/Edge/Firefox x Win/macOS/Linux x v129-131)

- 确定性 UA 轮换 get_ua_for_domain(): SHA-256 按域名固定 UA, 会话内稳定跨进程可复现

- WAF 指纹库 _detect_anti_bot(): 识别 Cloudflare/Imperva/PerimeterX/DataDome/Akamai/通用, 全文档扫描

- Retry-After 遵守: 429/503 读取 header (数字或 HTTP date) 作为最小重试延迟

- 退避封顶 60s (原无上限, N=10 时 1536s 卡死进程)

抓取稳定性:

- requests.Session 复用: 连接池(10/host) + cookie 持久化 + TLS 会话恢复

- 超时分离 (connect, read) 元组, 避免大页面浪费已建连接

- Wayback Machine 兜底: 404/403/超时自动重试 web.archive.org, 默认启用 --no-fallback 关闭

- AdaptiveThrottle 自适应限流: 3 次失败翻倍延迟+减半并发, 5 次成功渐进恢复, 429 全局暂停 30s

- readability-lite 提取: article/main 缺失时按文本密度选最可能正文 div

新增 CLI flags:

- --fetch-report: 结构化抓取报告到 stderr (每 URL 状态/WAF 类型/兜底方式/字符数 + JSON 摘要)

- --no-fallback: 禁用 Wayback 兜底

- --referer: 设置 Referer 头 (默认实例 URL)

- --request-delay: 抓取请求间隔秒数 (默认 0.3, 自适应可能增大)

fetch 结果新字段: anti_bot_detected (bool), waf_type (str|null), fallback_used (str|null)

测试: 新增 4 个测试文件 (test_browser_headers/test_anti_bot/test_wayback_fallback/test_adaptive_throttle), 451 个测试全部通过
This commit is contained in:
2026-08-01 21:34:57 +08:00
parent ea7a60a460
commit 28ff7c0a48
12 changed files with 2003 additions and 75 deletions
+30 -4
View File
@@ -160,6 +160,10 @@ python scripts/search.py -q "查询词" -i https://your-instance \
[--no-dedup] \
[--max-results 10] \
[--fetch 3] \
[--fetch-report] \
[--no-fallback] \
[--referer URL] \
[--request-delay 0.3] \
[--cache-ttl 30] \
[--queries-file queries.txt] \
[--include-domain example.com] \
@@ -186,6 +190,10 @@ python scripts/search.py -q "查询词" -i https://your-instance \
| `--no-dedup` | 禁用跨引擎去重 | 默认开启去重 |
| `--max-results` | 限制结果数(去重+排序后截取) | 不限 |
| `--fetch N` | 自动抓取前 N 个结果的网页正文 | 0(不抓取) |
| `--fetch-report` | v2.0.0 抓取报告(stderr,含 WAF/兜底/限流统计) | 关闭 |
| `--no-fallback` | v2.0.0 禁用 Wayback Machine 兜底 | 默认启用兜底 |
| `--referer` | v2.0.0 设置 Referer 头 | 实例 URL |
| `--request-delay` | v2.0.0 抓取请求间隔秒数(自适应限流可能增大) | 0.3 |
| `--cache-ttl` | 缓存分钟数 | 0(不缓存) |
| `--queries-file` | 批量查询文件(每行一个查询) | — |
| `--include-domain` | 域名白名单 | — |
@@ -210,6 +218,7 @@ python scripts/fetch.py -u https://example.com \
[--timeout 15] \
[--retries 3] \
[--no-redirect] \
[--referer https://google.com/] \
[--proxy http://corp:8080] \
[--auth-bearer-file ~/.token]
```
@@ -220,9 +229,10 @@ python scripts/fetch.py -u https://example.com \
| `-e / --extract` | 提取模式:text/html/markdown | text |
| `--encoding` | 强制字符编码 | 自动检测 |
| `--max-size` | 最大字节数 | 不限 |
| `--timeout` | 超时秒数 | 15 |
| `--timeout` | 超时秒数v2.0.0 内部拆分为 connect/read | 15 |
| `--retries` | 重试次数 | 3 |
| `--no-redirect` | 不跟随重定向 | 跟随 |
| `--referer` | 设置 Referer 头(v2.0.0 反爬措施) | — |
| `--proxy` | 代理 URL | — |
| `--auth-bearer-file` | Bearer Token 文件 | — |
| `--auth-basic-file` | Basic Auth 文件 | — |
@@ -249,6 +259,22 @@ python scripts/fetch.py -u https://example.com \
- text:提取纯文本
- html:原始 HTML
- markdown:增强 Markdown 转换(GFM 表格、代码块、引用块、嵌套列表、定义列表)
- v2.0.0 readability-lite`<article>`/`<main>` 缺失时,用文本密度算法选最可能正文的 `<div>`
**反爬与抓取稳定性(v2.0.0**
- 浏览器指纹头:`build_browser_headers()` 发送完整 Sec-Ch-Ua / Sec-Fetch-* / Accept-Language,不仅靠 User-Agent
- 12 个 UA 池:Chrome/Edge/Firefox × Windows/macOS/Linux × 129-131 版本
- 确定性 UA 轮换:`get_ua_for_domain()` 用 SHA-256 为每个域名固定一个 UA(会话内稳定,跨进程可复现)
- requests.Session 复用:连接池 + cookie 持久化 + TLS 会话恢复
- 超时分离:`(connect, read)` 元组,避免大页面下载中途超时浪费已建连接
- Retry-After 遵守:429/503 响应读取 Retry-After header(数字或 HTTP date)作为最小重试延迟
- 退避封顶 60s:原公式无上限,N=10 时达 1536s 会卡死进程
- WAF 指纹库:识别 Cloudflare / Imperva / PerimeterX / DataDome / Akamai / 通用反爬页,全文档扫描(非仅前 2000 字符)
- Wayback Machine 兜底:404/403/超时自动尝试 `https://web.archive.org/web/2/<url>`,默认启用,`--no-fallback` 关闭
- 自适应限流:`AdaptiveThrottle` 状态机,连续 3 次失败自动翻倍延迟 + 减半并发,429 触发全局暂停 30s
- `--fetch-report`:结构化抓取报告到 stderr(每 URL 状态/WAF 类型/兜底方式/字符数 + JSON 摘要)
- `--referer` / `--request-delay`:精细控制 Referer 头和请求间隔
- fetch 结果新增字段:`anti_bot_detected`bool)、`waf_type`str|null)、`fallback_used`str|null
**缓存**
- SQLite 缓存(`--cache-ttl`),相同查询在 TTL 内跳过网络
@@ -261,7 +287,7 @@ python scripts/fetch.py -u https://example.com \
- 凭证文件权限警告(POSIX
**工程**
- 共享 `common.py`(统一重试/字符集/认证/日志)
- 共享 `common.py`(统一重试/字符集/认证/日志/UA池/浏览器头/退避
- 结构化日志(`--verbose` / `--quiet`
- UTF-8 stdout 强制(`force_utf8_stdout()`,修复 Windows GBK 崩溃)
- Windows 配置路径发现(`%APPDATA%/searxng-cli/`
@@ -271,7 +297,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` 字段区分成功/失败)
- 362 个单元+集成测试
- 451 个单元+集成测试
## 跨 Agent 兼容性
@@ -299,7 +325,7 @@ pip install pytest
pytest -q
```
362 个测试覆盖:缓存操作、认证解析、域名过滤、Markdown 转换、搜索逻辑、集成流程、日志配置、HTML 回退、自动抓取、健康检查、输出格式化、实例解析、并行搜索、CLI 端到端、错误码分类、流式输出、进度事件、配置文件认证、schema_version、recovery_hint、batch 统一 schema、--dump-schema、UTF-8 stdout 强制、Windows APPDATA 路径。
451 个测试覆盖:缓存操作、认证解析、域名过滤、Markdown 转换、搜索逻辑、集成流程、日志配置、HTML 回退、自动抓取、健康检查、输出格式化、实例解析、并行搜索、CLI 端到端、错误码分类、流式输出、进度事件、配置文件认证、schema_version、recovery_hint、batch 统一 schema、--dump-schema、UTF-8 stdout 强制、Windows APPDATA 路径、v2.0.0 浏览器指纹头、WAF 反爬检测、Wayback Machine 兜底、自适应限流
## 项目结构