9小时前
|
|
|
对于独立开发者来说,想要在自己的应用(比如 AI 助手、内容聚合站)里加入“联网搜索”功能,一直是个痛点:
* **Google Custom Search API:** 每天免费 100 次,超过后价格昂贵。
* **Bing Search API:** 申请门槛高,且免费额度不仅少还限制并发。
* **直接爬虫:** 容易被封 IP,需要维护复杂的代理池。
**SearXNG** 是一个非常棒的开源元搜索引擎,它可以聚合 Google, Bing, DuckDuckGo 等几十个引擎的结果。但官方推荐的部署方式比较“重”,通常需要 Redis 来做缓存和限流,还要跑一个 Web 界面,对于小配置 VPS(比如 1核 512M/1G)来说负担略重。
本文将记录**如何将 SearXNG 裁剪到极致**:**移除 Redis、移除 UI 渲染、只保留 JSON 接口**,把它变成一个纯粹的、轻量级的私有搜索微服务。
-----
## 准备工作
* 一台 VPS(任意配置,只要能跑 Docker 即可)。
* 已安装 Docker 和 Docker Compose。
-----
## 第一步:规划目录结构
为了保持清爽,我们在服务器上创建一个独立的目录:
```bash
mkdir -p my-searxng/searxng
cd my-searxng
touch docker-compose.yml
touch searxng/settings.yml
```
现在的结构应该是这样的:
```text
my-searxng/
├── docker-compose.yml # 容器编排
└── searxng/
└── settings.yml # 核心配置(挂载进容器)
```
-----
## 第二步:编写 docker-compose.yml
通常 SearXNG 需要配合 Redis 容器运行,但既然我们是自用 API,可以通过配置关掉限流功能,从而**彻底抛弃 Redis**。
编辑 `docker-compose.yml`:
```yaml
version: '3'
services:
searxng:
image: searxng/searxng:latest
container_name: searxng-api
restart: always
ports:
- "8080:8080"
volumes:
# 【关键】挂载本地配置文件覆盖容器默认配置
- ./searxng:/etc/searxng:rw
environment:
- SEARXNG_BASE_URL=http://localhost:8080/
# 必要的安全与权限配置
cap_drop:
- ALL
cap_add:
- CHOWN
- SETGID
- SETUID
# 限制日志大小,防止塞满硬盘
logging:
driver: "json-file"
options:
max-size: "1m"
max-file: "1"
```
-----
## 第三步:配置 settings.yml (核心魔改)
这是最关键的一步。我们需要在配置中显式关闭所有依赖 Redis 的功能(Limiter 和 Image Proxy),并强制开启 JSON 输出。
编辑 `searxng/settings.yml`:
```yaml
# 继承默认配置
use_default_settings: true
general:
debug: false
instance_name: "My Private Search API"
search:
safe_search: 0 # 0=None, 1=Moderate, 2=Strict
autocomplete: "" # API 不需要自动补全
formats:
- json # 显式开启 JSON 格式支持
server:
port: 8080
bind_address: "0.0.0.0"
secret_key: "ChangeMeToSomethingRandom" # 必须修改,随意填字符串
# 【魔改核心 1】关闭限流器 (因为我们移除了 Redis)
limiter: false
# 【魔改核心 2】关闭图片代理 (API 只需要 URL,不需要服务器代下载图片)
image_proxy: false
default_http_headers:
X-Content-Type-Options: nosniff
# 【魔改核心 3】显式禁用 Redis 连接
redis:
url: false
# UI 设置 (虽然我们只用 API,但为了防报错保留基础配置)
ui:
static_use_hash: true
```
-----
## 第四步:解决权限坑 (The Gotcha)
SearXNG 容器内部使用 `searxng` 用户(UID 977)运行。如果不修改挂载目录的权限,容器启动时会因无法读取 `settings.yml` 而崩溃。
在 `my-searxng` 目录下执行:
```bash
# 暴力解法 (简单粗暴)
sudo chmod -R 777 ./searxng
# 或者 优雅解法 (推荐)
# sudo chown -R 977:977 ./searxng
```
-----
## 第五步:启动与测试
一切就绪,启动容器:
```bash
docker compose up -d
```
查看日志确认启动成功:
```bash
docker logs -f searxng-api
```
*如果你看到 "Listening on 0.0.0.0:8080" 且没有 Redis 报错,恭喜你,成功了!*
### API 调用测试
现在,你可以通过简单的 HTTP 请求来搜索了。
**请求 URL 格式:**
`http://你的服务器IP:8080/search?q={关键词}&format=json`
**示例:**
在浏览器访问 `http://1.2.3.4:8080/search?q=Python教程&format=json`
你将获得一段标准的 JSON 数据,包含标题、链接、摘要等信息,非常适合直接喂给 LLM (ChatGPT/Gemini) 做 RAG(检索增强生成)。
-----
## 进阶:Python 调用示例
既然搭建好了,我们写一段 Python 代码来封装这个搜索服务:
```python
import requests
def search_web(query, engines="google,duckduckgo"):
url = "http://localhost:8080/search"
params = {
"q": query,
"format": "json",
"engines": engines, # 指定使用哪些引擎
"language": "zh-CN"
}
try:
response = requests.get(url, params=params)
data = response.json()
results = []
if "results" in data:
for item in data["results"][:5]: # 取前5条
results.append({
"title": item.get("title"),
"link": item.get("url"),
"snippet": item.get("content")
})
return results
except Exception as e:
print(f"搜索出错: {e}")
return []
# 测试
res = search_web("2025年高分科幻电影")
for r in res:
print(f"[{r['title']}] - {r['link']}")
```
-----
## 总结与注意事项
通过移除 Redis 和 UI 组件,我们得到了一个**极度轻量**的搜索微服务。
**注意事项:**
1. **没有限流保护:** 因为去掉了 Redis,如果你的代码写了死循环疯狂请求接口,Google 会封锁你 VPS 的 IP。请务必在你的客户端代码(Python/Go)里通过 `sleep` 自行控制频率。
2. **引擎选择:** 如果 Google 经常跳验证码,可以在请求参数里指定 `engines=bing,duckduckgo` 来避开。
3. **私有化:** 建议不要将 8080 端口直接暴露给公网,或者配合 Nginx 加一个密码验证,防止被他人滥用。
这个方案非常适合用于个人开发者的 **AI 选片助手**、**新闻聚合器** 或 **自动化监控脚本**。希望能帮到大家!
🫵 来啊,说点有用的废话!
▲