引擎链是怎么解析出来的
请求进来时,服务器按下面四条规则算出有序的可用引擎列表:
-
显式链优先 ——
SEARCH_ENGINE可以是逗号分隔的链,例如bing,duckduckgo或brave,tavily。 -
auto走区域默认 —— 值为auto(或不设置)时, 根据region是否为cn-*选择国内链或海外链。 -
剔除不可用项 —— 未知引擎名被忽略;付费引擎(
brave/tavily) 在没有对应 API Key 时被剔除,不会阻塞启动,只在 stderr 打一条 warn。 - 免费引擎兜底 —— 所有免费引擎会作为故障转移候选追加到链尾(去重,付费项保持在前)。
此外,开启 SEARCH_LANG_ROUTING=1 时,含中文的查询会把原生中文引擎
(baidu → sogou → so360)提到其他免费引擎之前,付费引擎仍保持最高优先级。
该开关默认关闭 —— 因为在数据中心 / 海外网络下,百度与搜狗往往会先失败,反而拖慢首次响应。
区域默认链
| 区域 | 默认链 | 适用网络 |
|---|---|---|
cn-zh 及其它 cn-* |
bing → so360 → baidu → sogou |
中国大陆,可全部直连,无需代理 |
| 其它 / 未设置 | google → bing → duckduckgo → yandex |
海外部署或已配置代理 |
别名
引擎名不区分大小写,以下别名等价:
- duckduckgo
ddg - so360
haosou·360 - yandex
ya
九个引擎
bing — 全球通用,最稳的选择
- 费用免费,无需 Key
- 时效过滤支持,映射为
qft=+filterui:age-lt<秒数> - 区域全球;中国大陆默认链的首位,免代理直连
中英文覆盖都比较均衡,是默认配置下命中率最稳定的引擎。注意它对中文分词较弱 —— 这也正是「20xx 年」查询会被自动改写的原因(见工具指南)。
so360 — 国内最稳的中文原生引擎
- 费用免费,无需 Key
- 时效过滤不支持
- 区域中国大陆直连
在数据中心 / 机房 IP 下实测,它是纯 HTTP 客户端中唯一稳定可用的国内原生中文引擎 (百度会返回图形验证码,搜狗缺少 JS 生成的 SNUID 会被 302 拦回)。反爬相对宽松,因此被放在国内链的第二位。
so.com/link?m=... 形式的跳转封装,真实域名无法在服务端还原,
因此这类结果的 domain 会报告为 so.com。
baidu — 中文索引强,反爬严格
- 费用免费,无需 Key
- 时效过滤不支持(SERP 参数不稳定)
- 区域仅限中国大陆
中文索引质量好,但反爬严格:数据中心 / 海外 IP 下即使带了通过首页播种的 BAIDUID Cookie,
仍可能被强制跳到图形验证码(wappass)。在大陆住宅 IP 环境下配合
SEARCH_LANG_ROUTING=1 才能发挥优势。
sogou — 微信内容覆盖好
- 费用免费,无需 Key
- 时效过滤不支持
- 区域仅限中国大陆
独家优势是微信生态内容覆盖。限制在于它依赖 JS 生成的 SNUID 会话 ——
纯 HTTP 客户端拿不到时会被 antispider 以 302 拦回,因此在国内链中排在最后。
duckduckgo — 隐私友好的全球备选
- 费用免费,无需 Key
- 时效过滤支持,映射为
df=YYYY-MM-DD..YYYY-MM-DD - 区域全球;中国大陆直连通常需要代理
用 region 传递 DDG 的 kl 区域码(如 cn-zh、us-en)。
google — 索引质量最佳,但限海外
- 费用免费,无需 Key
- 时效过滤不支持
- 区域海外专用,墙内不可达
索引覆盖面与排序质量全球最佳,但反爬严格:需要海外 IP,并使用播种的 CONSENT / NID
会话 Cookie。命中挑战页(/sorry/ 或 JS 壳页面)时会被识别为失败并自动转移。
yandex — 俄语 / CIS 内容强项
- 费用免费,无需 Key
- 时效过滤不支持
- 区域海外;反爬中等
面向俄语与独联体地区内容,在部分网络环境下可达性反而更好。会播种 yandexuid 会话,并检测 SmartCaptcha。
brave — 付费,质量高且有免费额度
- 费用付费,需
BRAVE_API_KEY - 时效过滤支持,映射为
freshness=pd|pw|pm|py - 区域官方 API,按
country参数
tavily — 付费,专为 LLM / RAG 设计
- 费用付费,需
TAVILY_API_KEY - 时效过滤支持,请求体
time_range=day|week|month|year - 区域官方 API
检索结果本身就是为语言模型消费而优化的。自定义时间窗(非 day/week/month/year 的粒度)会回落到 month。
健康状态与优雅降级
每次引擎调用都会记录成功/失败。连续失败或遭遇限频的引擎会进入冷却期, 冷却期内该引擎被引擎链直接跳过 —— 不再对已知失败的引擎浪费请求,也避免反复触发对方的反爬机制。
| 状态 | 含义 | 链行为 |
|---|---|---|
untested | 本进程内未使用过 | 尝试 |
healthy | 最近一次成功 | 尝试 |
degraded | 有连续失败但未达阈值 | 尝试 |
cooling | 冷却中(含冷却截止时间) | 跳过 |
RATE_LIMITED→ 立即冷却,时长取retryAfter,默认 60 秒;- 其他失败 → 连续 2 次后冷却。
当所有引擎都失败时,search 的错误响应会带上一份引擎状态快照与逐引擎归因摘要
(例如 bing=RATE_LIMITED (冷却至 13:45), baidu=验证码...),并区分
「全部处于冷却」(疑似网络受限或 IP 被临时限制)与普通失败,给出不同的行动建议。
选型建议
| 你的场景 | 推荐配置 |
|---|---|
| 中国大陆,只想快速跑通 | SEARCH_REGION=cn-zh(默认链即可,免代理) |
| 中国大陆住宅 IP,追求中文效果 | SEARCH_REGION=cn-zh + SEARCH_LANG_ROUTING=1 |
| 海外部署 | 不设置 SEARCH_REGION,默认走 google → bing → duckduckgo → yandex |
| 质量优先,愿意付费 | SEARCH_ENGINE=brave,tavily,bing + 对应 API Key(付费引擎在前,免费兜底) |
| 墙内需要 DDG / Brave / Tavily | 配置 SEARCH_HTTP_PROXY=http://127.0.0.1:7890 |
| 只要最稳、不要惊喜 | SEARCH_ENGINE=bing 或 SEARCH_ENGINE=bing,so360 |
引擎改版了怎么办
所有引擎的 SERP 解析规则(标题 / URL / 摘要的提取正则、反爬检测关键词)都外置成 JSON,
放在仓库的 src/selectors/*.json。
当某个引擎改版导致解析失效时,不必等新版本发布 —— 按优先级覆盖即可:
- 内置规则(随包分发,默认)
- 本地文件 ——
SEARCH_SELECTOR_FILE=/path/selectors.json - 远程 URL ——
SEARCH_SELECTOR_OVERRIDE_URL=https://gist.githubusercontent.com/.../selectors.json(启动时拉取,优先级最高)
覆盖文件按引擎 key 做合并,未提到的引擎保持内置规则。加载失败(文件损坏或网络不通) 永远不会阻塞启动,只会自动回退上一级规则并打印 warn 日志。 详细字段格式见配置指南。
合规边界
工具只返回搜索摘要与链接,不转载全文内容,并遵循目标站点的 robots.txt 与服务条款。
百度与搜狗基于公开 HTML 解析,若其页面结构调整可能导致解析失效 —— 这时请使用上文的规则覆盖机制。