内容
# 网页抓取工具
CLI-first 网站抓取 + 匿名浏览器获取。
- **SSRF安全** 公共 `http(s)` 仅限
- **robots.txt** 尊重(缺少/无法访问的 robots 时失败打开)
- **保护分类** — 阻止 / 验证码 / Cloudflare / 登录 / 速率限制状态,而不是垃圾文本
- **可选 CapSolver** — 转stile + Cloudflare “Just a moment…” 清除(粘性住宅代理;CapSolver 需要 **socks5** for Webshare)
- **薄 MCP 适配器** — 相同的库通过 JSON-RPC HTTP
> 默认情况下**不**绕过保护。 CapSolver 通过 env 方式开启。 没有社交登录配置文件或 cookie 被重复使用。
## 安装
```bash
git clone https://github.com/teslashibe/web-scrape.git
cd web-scrape
npm install
npx playwright install chromium # 用于 `fetch` / 浏览器路径
```
Node **≥ 20**. 使用 `undici` **v7** (与 Node 20 兼容)。
## CLI(代理的首选)
```bash
# 可读的浏览器获取(Playwright)
./bin/web-scrape.mjs fetch https://example.com/ --json
# 结构化的单页抓取(HTTP + HTML 提取)
./bin/web-scrape.mjs scrape https://example.com/ --json
# MCP HTTP 服务器(默认 :8091)
./bin/web-scrape.mjs serve --port 8091
```
退出代码:`0` ok · `2` 结构化非 ok 状态 · `1` 使用错误。
## 库
```js
import { scrape, browserFetchURL } from "web-scrape";
const page = await browserFetchURL({ url: "https://example.com/" });
const brief = await scrape({ url: "https://example.com/" });
```
## Docker / Kubernetes
```bash
docker build -t web-scrape .
docker run --rm -p 8091:8091 \
-e WEB_FETCH_TURNSTILE_PROVIDER=capsolver \
-e WEB_FETCH_TURNSTILE_API_KEY=CAP-...
-e WEBSHARE_RESIDENTIAL_USER=...
-e WEBSHARE_RESIDENTIAL_PASS=...
-e WEBSHARE_USERNAME_TEMPLATE='{user}-{country}-1'
web-scrape
```
公开服务端口 `8091`. 探测 `GET /mcp/v1/ready` (200 ready / 503 not_ready)。
## MCP
```
POST /mcp/v1 JSON-RPC 2.0 (初始化,工具/列表,工具/调用)
GET /mcp/v1/health 存活 + 限制 + 指标
GET /mcp/v1/ready 准备就绪
```
工具:
| 工具 | 目的 |
| --- | --- |
| `browser_fetch_url` | 短暂的 Playwright 获取 → 可读文本或结构化状态 |
| `scrape_website_context` | 单页 HTTP 抓取 → 标题/摘要/产品/受众字段 |
## CapSolver + 代理(可选)
| 环境变量 | 目的 |
| --- | --- |
| `WEB_FETCH_TURNSTILE_PROVIDER=capsolver` | 启用提供商 |
| `WEB_FETCH_TURNSTILE_API_KEY` | CapSolver 密钥 |
| `WEBSHARE_RESIDENTIAL_USER` / `PASS` | 住宅代理 |
| `WEBSHARE_USERNAME_TEMPLATE` | 首选粘性 `{user}-{country}-1` (需要 `cf_clearance` IP 亲和力)|
| `WEB_SCRAPER_PROXY_URL` | 完整代理 URL 重写 |
| `BROWSER_FETCH_TIMEOUT_MS` | Playwright截止日期(默认情况下,当 CapSolver+代理设置时上升;最大 180s) |
CapSolver `AntiCloudflareTask` 作为 `socks5:host:port:user:pass` 发送(无页面 `html` — CapSolver 拒绝它为 `invalid html`)。 Playwright 出口保留 HTTP 代理。托管的“Just a moment…”页面使用 AntiCloudflareTask,即使存在 Turnstile iframe。 永远不要记录代理凭据或 API 密钥。
## 测试
```bash
npm test # 单元测试夹具(无实时网络)
npm run validate # 回环 MCP 发现/调用
npm run smoke # 状态矩阵冒烟测试
```
## 许可证
Apache-2.0. CapSolver / Webshare 是可选的第三方付费服务 — 您需要提供自己的密钥。