用 Python + Flask 实现一个兼容 SearXNG 接口的本地搜索服务,支持深度网页抓取
背景
在搭建个人 AI 助手时,常遇到一个问题:大模型的知识有截止日期,无法获取最新信息。虽然可以接入搜索引擎 API,但商用服务价格不菲,免费版又有调用次数限制。
于是我写了一个轻量级的本地搜索代理服务,它本质上是把百度搜索包装成 SearXNG 兼容的 API 接口,同时加入深度网页抓取能力——不仅返回搜索结果,还能自动抓取排名靠前的页面正文,让 AI 直接阅读原文内容。
功能概览
| 功能 | instructions |
|---|---|
| 百度搜索 | 基于 baidu_serp_api 模拟百度搜索,获取标题、链接、摘要 |
| 深度抓取 | 异步并发抓取 Top N 个结果页面,提取正文并附加到摘要中 |
| 多提取器 | 自动降级使用 trafilatura / readability / goose3 |
| 缓存机制 | 搜索结果缓存 1 小时,降低重复请求 |
| 限频保护 | 随机延迟 + 冷却机制,降低风控概率 |
| API 兼容 | 输出格式与 SearXNG 保持一致,可直接对接各类 AI 应用 |
工作流程
用户请求 → Flask服务 → 百度搜索API → 获取结果列表
↓
(可选)深度抓取 Top N
↓
并发提取正文内容
↓
质量评分 + 内容附加
↓
返回SearXNG兼容JSON
快速上手
1. 安装依赖
pip install flask baidu-serp-api trafilatura readability-lxml aiohttp fake-useragent
可选安装(提高提取成功率):
pip install goose3
2. 启动服务
python SearxBaiduService.py
或者直接双击 RunSearcher.bat(Windows)。
服务默认运行在 http://localhost:8888.
3. 调用示例
# 普通搜索
curl "http://localhost:8888/search?q=人工智能最新进展"
# 限制返回条数
curl "http://localhost:8888/search?q=深度学习&count=4"
# 禁用深度抓取
curl "http://localhost:8888/search?q=Transformer&deep_crawl=false"
# 指定深度抓取条数
curl "http://localhost:8888/search?q=大模型&deep_count=2"
4. 返回格式(SearXNG 兼容)
{
"query": "人工智能",
"number_of_results": 6,
"results": [
{
"title": "文章标题",
"url": "https://...",
"content": "摘要信息\n\n【深度抓取内容】\n正文内容...",
"source": "baidu",
"engine": "baidu"
}
]
}
关键参数调优
在代码开头的「可调参数区」可以调整以下参数:
| 参数 | default value | instructions |
|---|---|---|
DEFAULT_RESULT_COUNT | 6 | 默认返回结果数 |
DEEP_CRAWL_MAX_RESULTS | 6 | 最大深度抓取条数 |
DEEP_CRAWL_CONCURRENT | 2 | 并发抓取数(建议 ≤3) |
DEEP_CRAWL_TIMEOUT | 6 | 单页超时(秒) |
CACHE_TTL | 3600 | 缓存有效期(秒) |
RANDOM_DELAY_MIN/MAX | 5~10 | 搜索请求随机延迟(秒) |
ERROR_COOLDOWN | 60 | 失败后冷却时间(秒) |
深度抓取的实现要点
抓取正文时使用了三级降级策略::
- trafilatura:首选,提取质量最高,对中文支持好
- readability-lxml:备选,Mozilla 出品,稳定性好
- goose3:最后兜底,适合新闻类页面
每次抓取后还会进行质量评估(正文长度、中文比例、标题质量等),得分过低的页面不会附加内容,避免引入噪音。
Open WebUI 联网搜索配置
服务启动后,可以无缝对接 Open WebUI 的联网搜索功能。配置步骤如下:
procedure
- 登录 Open WebUI → 点击左下角管理员头像 → 管理员面板(Admin Panel)
- 导航到 设置 → 联网搜索(Web Search)选项卡
- 按以下参数填写:
| 配置项 | 推荐值 |
|---|---|
| 搜索引擎 | searxng |
| Searxng 查询接口地址 | http://localhost:8888/search |
| 搜索结果数量 | 1-3(推荐 2) |
| 并发请求数 | 0 |
| ✅ 绕过嵌入和检索 | 开启 |
| ✅ 绕过网页加载器 | 开启 |
| 网页加载引擎 | 默认 |
| 超时时间 | 5 秒 |
| SSL 验证 | 关闭 |
- 点击 保存
参数说明
- 搜索结果数量设为 1-3:配合深度抓取功能,数量过多会增加响应延迟。建议设为 2,既保证信息量又兼顾速度。
- 并发请求数设为 0:由本服务内部控制并发(
DEEP_CRAWL_CONCURRENT),避免在 Open WebUI 侧重复限流。 - 绕过嵌入和检索 + 绕过网页加载器:本服务已将深度抓取内容附加到
content字段,无需 Open WebUI 再额外加载页面,避免双重抓取和 IP 风控。 - SSL 验证关闭:本服务使用自签名/非标准证书时避免报错(本地环境安全)。
验证是否生效
在对话中输入需要实时信息的问题(如”今天有什么新闻?”),观察是否触发搜索请求。也可以在 Open WebUI 的日志中查看是否有 http://localhost:8888/search 的调用记录。
注意事项与免责声明
- 仅供学习研究使用,请勿用于商业或高频请求场景
- 百度搜索接口本质是模拟浏览器行为,存在被限制的风险,请合理控制请求频率
- 建议在本地或内网部署,不要暴露到公网
- 深度抓取会访问第三方网站,请尊重目标网站的 robots.txt 和服务条款
- 本项目不存储任何用户数据,所有缓存仅用于提升响应速度
以上配置基于 Open WebUI v0.9.x 版本,不同版本界面可能略有差异,核心参数保持一致。