内容
<p align="center">
<img src="assets/icon/solocrawl.png" alt="SoloCrawl logo" width="128">
</p>
<h1 align="center">SoloCrawl</h1>
<p align="center">
<strong>网络搜索、网页抓取和实时软件包版本查询 —<br>
为您的终端、代码和本地LLM服务。</strong><br>
无需账号。无需API密钥。无需云服务。
</p>
<p align="center">
<img src="https://img.shields.io/badge/python-3.14%2B-blue.svg" alt="Python 3.14+">
<img src="https://img.shields.io/badge/license-MIT-green.svg" alt="MIT License">
<img src="https://img.shields.io/badge/MCP-ready-8A2BE2.svg" alt="MCP ready">
<img src="https://img.shields.io/badge/API%20keys-none%20required-success.svg" alt="No API keys required">
</p>
---
SoloCrawl 是一个小型、自我托管、完全异步的Python工具,它擅长于三件事情:**搜索网络**、**抓取网页为干净的Markdown**,以及 **查询最新的软件包版本**。它运行在您的机器上,免费使用,并且安装后立即生效 — 无需注册,无需密钥。
它适用于个人开发者和本地LLM爱好者。您可以用它作为 **MCP服务器**(LM Studio、Claude Desktop、OpenCode等),直接从 **CLI** 或作为 **Python库**。
## ✨ 主要特点
| | |
|---|---|
| 🔌 **零配置** | 搜索、抓取和软件包查询都开箱即用 — 无需账号,无需密钥。 |
| 🔎 **联邦搜索** | 查询11个可能的来源,合并它们并使用互惠排名融合和重复URL去重为一个干净的排名。 |
| 📄 **智能抓取** | HTML → 整洁的Markdown,通过`trafilatura`/`readability`,对于JS较重的页面使用Playwright浏览器回退 — 仅在需要时使用。 |
| 📦 **实时软件包版本** | 10个生态系统(PyPI、npm、crates.io、Maven、Go等)从官方注册中心实时解析 — 永远不会有过时的本地数据库。 |
| 🤖 **MCP原生** | 直接作为stdio MCP服务器与五个现成的工具一起使用。 |
| ⚡ **完全异步,有限并发** | 一个共享的HTTP客户端,一个循环使用的浏览器,全局和每个域的并发限制。快速但不轰炸任何人。 |
| 🧩 **可扩展** | 添加搜索或软件包提供程序只需一个自注册文件 — 核心保持不变。 |
| 🔒 **默认安全** | 默认阻止localhost/私有/云元数据目标,并遵守`robots.txt`。 |
## 🚀 快速开始
安装SoloCrawl的推荐方法是 **pipx** — 它将`solocrawl`和`solocrawl-mcp`命令放入您自己的隔离环境中的PATH中,因此您可以从任何地方运行它们,而无需管理虚拟环境:
```bash
git clone https://github.com/hlavacm/solocrawl.git
pipx install ./solocrawl # 或绝对路径:pipx install /path/to/solocrawl
```
> 已经在PyPI上?那么只需 `pipx install solocrawl` — 无需检出。
就是这样 — 现在从任何目录运行这三个核心命令:
```bash
# 抓取页面为Markdown
solocrawl scrape https://example.com
# 联邦网络搜索(默认为Wikipedia + DuckDuckGo + StackExchange)
solocrawl search "python asyncio semaphore" --limit 5
# 实时软件包版本查询
solocrawl package requests --ecosystem pypi
```
### 更新
```bash
# 从PyPI安装:
pipx upgrade solocrawl
# 从本地检出安装 — 拉取最新更改,然后重新安装:
cd /path/to/solocrawl && git pull && pipx install --force . # 别名:pipx reinstall solocrawl
```
升级后,重启您的MCP客户端(LM Studio、Cursor、Claude Desktop等),使其拾取新的`solocrawl-mcp`二进制文件 — 您的`mcp.json`无需更改,只要它指向`solocrawl-mcp`在您的PATH上。
## 您可以使用
### 🔎 搜索网络
一个查询,多个来源,一个合并的排名 — 没有单个提供者决定一切为您。
```bash
solocrawl search "python asyncio semaphore" --limit 5
# 精确选择要命中的来源,并获取机器可读的输出
solocrawl search "django orm" --sources wikipedia,stackexchange --json
```
### 📄 抓取页面为干净的Markdown
将任何URL转换为LLM-ready Markdown,并附带页面元数据(标题、作者、日期...)作为前言。
```bash
solocrawl scrape https://example.com
# 保存到文件,或强制浏览器获取JS渲染的页面
solocrawl scrape https://example.com --out page.md
solocrawl scrape https://example.com --force-browser
```
### 📦 查询软件包版本
从官方注册中心获取当前版本和满足您约束的版本。
```bash
solocrawl package react --ecosystem npm --constraint ">=18,<19"
solocrawl package monolog/monolog --ecosystem packagist --json
solocrawl package some-lib --ecosystem pypi --allow-prerelease
```
### 🧪 一键研究
经典的LLM工作流 — 搜索,抓取顶部结果,并返回聚合的**引用**报告。
```bash
solocrawl research "python asyncio semaphore" --depth 3
```
### 🗂️ 批量抓取多个URL
在相同的并发限制下,一次性获取整个列表;`--out-dir` 将为每个URL写入一个文件。
```bash
solocrawl batch https://example.com https://www.python.org --out-dir /tmp/scrape
solocrawl batch --from-file urls.txt --out-dir /tmp/scrape
```
### …并查看可用功能
```bash
# 列出每个注册的提供者(搜索 + 软件包),默认 vs. 选择加入
solocrawl providers
```
## 🤖 与您的本地LLM(MCP)一起使用
这就是SoloCrawl的真正优势 — 为您的本地模型(LM Studio、OpenCode、Claude Desktop等)提供搜索、抓取和版本查询功能。`pipx install`已经将`solocrawl-mcp`放入您的PATH中,因此您只需在MCP客户端中指向它。
**LM Studio / Claude Desktop** — [examples/mcp.json](examples/mcp.json)中的即用配置。将它放入客户端的MCP设置(`mcp.json`)中:
```json
{
"mcpServers": {
"solocrawl": {
"command": "solocrawl-mcp",
"args": [],
"env": {
"SOLOCRAWL_LOG_LEVEL": "INFO",
"SOLOCRAWL_LOG_FILE": "~/.local/state/solocrawl/mcp.log"
}
}
}
}
```
**OpenCode** — 使用不同的配置格式。复制 **examples/opencode.jsonc** 到 `~/.config/opencode/opencode.jsonc`(全局)或项目根目录下的`opencode.jsonc`。OpenCode期望`type: "local"`、`command`作为数组,以及`environment`代替`env`。
如果您的MCP客户端不继承您的shell `PATH`,请将`"solocrawl-mcp"`替换为`which solocrawl-mcp`的完整路径(通常为`~/.local/bin/solocrawl-mcp`,在`pipx install`后)。日志输出到stderr(在LM Studio开发者日志中可见),并可选地输出到`SOLOCRAWL_LOG_FILE`。
服务器公开 **五个工具**:
- `web_search(query, limit=5, sources=None)` — 跨启用提供者的联邦搜索
- `scrape(url)` — 从URL中获取和提取Markdown(带有页面元数据)
- `research(query, depth=3)` — 搜索,抓取顶部结果,并返回聚合的引用报告
- `package_version(name, ecosystem, constraint=None, allow_prerelease=False)` — 实时注册中心查询
- `list_providers(provider_type="all")` — 列出注册的搜索/软件包提供者(默认 vs. 选择加入)
要检查活动版本和命令路径:
```bash
pipx list | grep solocrawl
which solocrawl-mcp
```
> **在本地克隆中工作?** 安装的`solocrawl-mcp`是一个**快照** — 编辑存储库不会更新`PATH`上的命令,因此您的MCP客户端继续运行旧代码。在更改源代码后,使用`pipx install --force .`刷新它(或使用`pipx install --editable .`安装,以便自动拾取未来编辑)。
## 🐍 从Python使用
```python
import asyncio
from solocrawl.config import load_config
from solocrawl.core.search import federated_search, select_providers
from solocrawl.core.search.providers import duckduckgo, stackexchange, wikipedia # noqa: F401
async def main() -> None:
providers = select_providers(load_config())
results = await federated_search(providers, "asyncio python", limit=3)
for result in results:
print(result.title, result.url)
asyncio.run(main())
```
参见 [examples/library_search.py](examples/library_search.py) 以获取可运行的示例。
## 搜索提供者
**默认(零配置,始终启用):**
| 提供者 | 来源 |
|----------|--------|
| `wikipedia` | MediaWiki API |
| `duckduckgo` | `ddgs` 包 |
| `stackexchange` | Stack Exchange API(Stack Overflow) |
**选择加入**(通过`SOLOCRAWL_ENABLE_PROVIDERS`启用):
| 提供者 | 来源 |
|----------|--------|
| `wikidata` | Wikidata实体搜索 |
| `hackernews` | Hacker News(Algolia) |
| `arxiv` | arXiv Atom API |
| `pubmed` | PubMed/NCBI E-utilities |
| `github` | GitHub仓库搜索 |
| `mdn` | MDN Web Docs搜索 |
| `reddit` | Reddit帖子搜索(`search.json`) |
| `searxng` | 自托管的SearXNG(设置`SOLOCRAWL_SEARXNG_URL`) |
```bash
SOLOCRAWL_ENABLE_PROVIDERS=arxiv,hackernews solocrawl search "transformer attention" --limit 6
SOLOCRAWL_ENABLE_PROVIDERS=github,mdn solocrawl search "fetch api" --limit 6
```
## 软件包注册中心
默认生态系统: **PyPI**、**npm**、**Packagist**、**crates.io**、**NuGet**、**Maven Central**、**RubyGems**、**Go modules**、**pub.dev**、**Swift**。版本始终从官方注册中心实时获取 — SoloCrawl不维护自己的版本数据库。Swift软件包没有中央注册中心,因此版本来自存储库的git标签(GitHub上的`owner/repo`)。
```bash
solocrawl package serde --ecosystem crates
solocrawl package Newtonsoft.Json --ecosystem nuget
solocrawl package org.junit.jupiter:junit-jupiter --ecosystem maven
solocrawl package github.com/gorilla/mux --ecosystem go
solocrawl package apple/swift-argument-parser --ecosystem swift
```
## 可选额外功能
```bash
# 用于JS较重的页面的浏览器回退(Playwright)
pip install -e ".[browser]"
playwright install chromium
solocrawl scrape https://example.com --force-browser
# 安装所有功能
pip install -e ".[all]"
```
## ⚙️ 配置
**所有默认值都无需配置即可工作。** 以下所有内容均为可选,并使用`SOLOCRAWL_`前缀。对于本地开发,请复制`.env.dist`到`.env`并取消注释您需要的部分 — SoloCrawl通过[python-dotenv](https://pypi.org/project/python-dotenv/)自动加载`.env`,并且现有的shell环境变量优先。
<details>
<summary>环境变量</summary>
| 变量 | 默认值 | 用途 |
|----------|---------|---------|
| `SOLOCRAWL_ENABLE_PROVIDERS` | _(空)_ | 以逗号分隔的选择加入提供者名称 |
| `SOLOCRAWL_SEARXNG_URL` | _(空)_ | 自托管SearXNG实例的基准URL(启用`searxng`提供者) |
| `SOLOCRAWL_RESPECT_ROBOTS` | `true` | 尊重`robots.txt`进行抓取(失败时打开);设置为`false`跳过 |
| `SOLOCRAWL_CACHE_TTL_SECONDS` | `0` | 秒为单位的内存获取缓存TTL(`0` = 禁用) |
| `SOLOCRAWL_MAX_CONCURRENCY` | `10` | 全局获取并发限制 |
| `SOLOCRAWL_PER_DOMAIN_LIMIT` | `2` | 每个域的并发限制 |
| `SOLOCRAWL_TIMEOUT_SECONDS` | `30` | 每个请求的超时时间,单位为秒 |
| `SOLOCRAWL_MAX_RETRIES` | `3` | 网络错误/速率限制时的重试次数 |
| `SOLOCRAWL_MAX_RESPONSE_BYTES` | `10485760` | 获取的响应正文大小上限(10 MiB);较大的正文会被截断 |
| `SOLOCRAWL_PROXY_ENABLED` | `false` | 启用可选代理层 |
| `SOLOCRAWL_PROXY_MODE` | `list` | 代理模式:`list`(旋转池)或`endpoint`(单个旋转端点) |
| `SOLOCRAWL_PROXY_LIST` | _(空)_ | 以逗号分隔的代理URL列表 |
| `SOLOCRAWL_PROXY_ENDPOINT` | _(空)_ | 单个旋转代理端点 |
| `SOLOCRAWL_PROXY_USERNAME` | _(空)_ | 代理身份验证用户名 |
| `SOLOCRAWL_PROXY_PASSWORD` | _(空)_ | 代理身份验证密码 |
| `SOLOCRAWL_ALLOW_INTERNAL_URLS` | `false` | 允许抓取localhost/私有IP(仅限开发) |
| `SOLOCRAWL_USER_AGENT` | _(SoloCrawl 默认)_ | 重写HTTP User-Agent进行API请求 |
| `SOLOCRAWL_BROWSER_ALLOWED` | `true` | 允许安装后使用Playwright |
| `SOLOCRAWL_LOG_LEVEL` | `WARNING` | 日志级别:`DEBUG`、`INFO`、`WARNING`、`ERROR` |
| `SOLOCRAWL_LOG_FILE` | _(空)_ | 可选日志文件路径(也记录到stderr) |
</details>
## 🔒 URL获取的安全注意事项
默认情况下,SoloCrawl拒绝获取localhost、链路本地、私有、保留和云元数据地址。它会检查字面主机、DNS解析的A/AAAA记录、HTTP重定向目标和Playwright的最终浏览器URL。SoloCrawl仍然是一个单用户本地工具,而不是一个具有敌意的多租户代理 — 不要将其暴露给不受信任的网络调用者。
`SOLOCRAWL_ALLOW_INTERNAL_URLS=true`完全禁用这些内部目标检查(仅适用于受信任的本地开发)。
## 🧩 扩展
插件布局的重点是可以添加一个源代码,只需一个自注册文件 — 核心永远不会更改。要添加搜索提供者:
1. 创建`src/solocrawl/core/search/providers/myprovider.py`实现`SearchProvider`。
2. 使用`@register("myprovider", zero_config=True)`或作为选择加入注册。
3. 在`src/solocrawl/core/search/providers/__init__.py`中导入模块,以便运行注册。
4. 在`tests/`中添加基于fixture的测试。
与`src/solocrawl/core/packages/providers/`下的软件包提供者相同的模式适用。
## 开发
在虚拟环境中使用可编辑安装的克隆文件中工作 — 这也会将`solocrawl`和`solocrawl-mcp`脚本放入`.venv/bin/`:
```bash
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
```
然后运行质量检查:
```bash
ruff check . && ruff format --check .
pyright
pytest
# …或全部一行:
ruff check . && pyright && pytest
```
## 伦理和使用条款
SoloCrawl适用于个人开发者和本地LLM工具。它尊重目标站点的`robots.txt`和服务条款 — `scrape`在默认情况下会咨询`robots.txt`并拒绝被禁止的URL(失败时打开;选择退出`SOLOCRAWL_RESPECT_ROBOTS=false`)。代理和抓取功能 **不** 用于绕过站点规则、验证码或反机器人系统。负责任地使用并保持在合法的访问模式下。
## 许可证
MIT - 参见 [LICENSE](LICENSE)。