Files

124 lines
7.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 通用爬虫系统 (universal-crawler)
基于原 tpu_crawlerPlaywright + stealth + 系统 Chrome)改造的全能网页爬取管理系统。
**可爬取任意网址**,自带 Web 管理界面,支持批量、定时、自动三种模式。
## 快速开始
```bash
./start.sh # 启动 (默认端口 16062)
./start.sh stop # 停止
./start.sh restart # 重启
./start.sh status # 查看状态
```
启动后打开管理界面:`http://<服务器IP>:16062/`
环境要求(本机已具备):
- Python 3.12 (`/home/hz1/miniconda3/envs/openclaw/bin/python`)
- flask / playwright / playwright-stealth
- 系统 Chrome `/usr/bin/google-chrome`
## 功能总览
### 1. 前端管理界面
- **总体统计区**:任务总数 / 运行中 / 累计运行次数 / 成功失败页面 / 图片数 / 磁盘占用
- **🔍 基本搜索**:顶部搜索框,按网址 / 标题 / 任务名即时查找已爬内容,可直接预览文件、查看元数据、跳转任务详情
- **🗑️ 回收站**:删除的任务统一进回收站(可恢复);只有手动在回收站中才能彻底删除或清空,防止误删
- **日间/夜间双主题**:右上角按钮一键切换,自动记忆选择
- 任务卡片总览:状态、进度、统计、下次调度时间一目了然
- 一键操作:开始 / 暂停 / 恢复 / 终止 / 编辑 / 删除
- 任务详情:历次运行记录、结果明细表(HTML/TXT 在线预览)、图片缩略图、实时日志
- **防误关保护**:新建/编辑弹窗有未保存修改时,点窗口外 / ESC / 关闭会先确认
- 运行中的任务参数支持**热更新**(修改后从下一页起生效)
### 2. 批量爬取模式
一次粘贴多个网址(每行一个,`#` 注释),或点击「📂 导入网址文件」上传 .txt 文件批量导入:
- **处理方式可选**:追加(保留已有,默认)或覆盖(清空已有)
- 自动识别 UTF-8/GBK 编码、自动去重、自动清理行内注释
可配置:
- 项目名称、输出目录(默认 `out/<任务ID>`,可填绝对路径)
- 爬取间隔(随机秒数区间,防封 IP)、单页超时
- 失败重试次数 / 重试间隔
- 是否爬取图片(自动下载页面图片到 `xxx_img/` 目录)
- 完成后邮件通知(复用 send_email.py,默认发到 wlq@tphai.com
### 3. 定时爬取模式
- **间隔调度**:每 N 分钟 / 小时 / 天,可指定**首次执行时间**(留空=尽快,已过时间立即执行)
- **cron 表达式**:5 段式(分 时 日 月 周,周 0/7=周日),如 `0 3 * * *` 每天凌晨 3 点,同样支持首次执行时间作为计算起点
- 可启用/停用调度,自动计算下次执行时间;到点自动开跑,跑完自动计算下一次
### 4. 自动爬取模式
给定一个起始网址,系统**持续递归**爬取:爬取页面 → 自动发现符合规则的链接 → 继续爬取 → 继续发现……直到**无新链接可爬**时自动结束。
- **🧪 试爬取**:先用起始网址试跑一次,展示规则筛选后的链接清单(将爬取哪些、排除哪些及原因),确认规则符合预期后再正式开爬
- **最大爬取深度**:0=无限制(默认),N=只爬 N 层
- **最大页数**:0=无限制,默认 1000 作安全上限(防止动态无限链接的站点失控)
- **🔄 缓存续爬**:提取但未爬取的链接自动存入缓存队列(连同已爬集合一并持久化),任务停止/中断后再次运行,从缓存队列**继续爬取**,已爬过的不会重复;起始网址每次运行都重新爬取(不去重);规则变更后可点「🧹 清空缓存」重新开始
- **包含规则**:只爬包含指定子串(或正则)的链接
- **排除规则**:跳过匹配的链接(如 login、/tag/
- **仅同域名**:限制在起始网站内
- 其余参数(间隔、重试、图片、通知)同批量模式
### 5. 资源操作信息(元数据)
每个爬取的网页和图片都自动生成 `.meta.json` 操作信息文件:
- **网页**`<文件名>.meta.json`):爬取模式(批量/定时/自动)、爬取时间、爬取网址、**来源链接**(自动模式下从哪个页面发现)、爬取深度、任务/运行 ID、页面标题、状态、尝试次数、文件列表、图片明细
- **图片集**`<文件名>_img/meta.json`):所属页面、来源链接、每张图片的原始 URL / 大小 / 下载时间
- 详情页结果表中点「📋 元数据」即可在线查看
### 6. 数据库记录(MySQL
任务、运行记录、爬取结果实时写入 MySQL(`121.40.164.32:16006`,账号 `uni_crawler`,库 `uni_crawler`),**网页完整内容不入库**(存磁盘文件),库中只存标题、网址、状态、文件路径等元数据:
- `crawl_tasks` — 任务信息(含回收站标记 deleted_at
- `crawl_runs` — 每次运行记录(状态/进度/成功失败数/图片数/时间)
- `crawl_results` — 每页一条(**status: OK/FAIL** 成功失败标记、标题、网址、来源链接、深度、错误信息、文件路径、图片数)
- 数据库不可用时自动降级,不影响爬取主流程;删除任务进回收站同步标记,彻底删除同步清库
## 输出文件
每个任务输出到独立目录(默认 `out/<任务ID>/`):
- `NNNN_<域名>_<时间戳>.html` — 完整网页
- `NNNN_<域名>_<时间戳>.txt` — 提取的纯文本正文
- `NNNN_<域名>_<时间戳>_img/` — 下载的图片(开启图片爬取时)
## API 速查
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | `/api/tasks` | 任务列表(含最新运行) |
| POST | `/api/tasks` | 创建任务 |
| GET/PUT/DELETE | `/api/tasks/<id>` | 详情 / 修改 / 删除 |
| POST | `/api/tasks/<id>/start` | 开始爬取 |
| POST | `/api/tasks/<id>/pause` | 暂停 |
| POST | `/api/tasks/<id>/resume` | 恢复 |
| POST | `/api/tasks/<id>/stop` | 终止 |
| GET | `/api/trash` | 回收站列表 |
| GET | `/api/search?q=` | 基本搜索(网址/标题/任务名子串匹配,轻量) |
| POST | `/api/trash/<id>/restore` | 从回收站恢复任务 |
| DELETE | `/api/trash/<id>` | 彻底删除单个(默认输出目录一并清理) |
| DELETE | `/api/trash` | 清空回收站 |
| POST | `/api/probe` | 试爬取(表单规则预览链接清单) |
| POST | `/api/tasks/<id>/probe` | 对已保存的自动任务试爬取 |
| GET | `/api/runs/<rid>` | 运行详情(结果+日志) |
| GET | `/api/runs/<rid>/logs?offset=N` | 增量日志 |
| GET | `/api/file?task_id=&path=` | 读取输出文件(HTML/TXT/图片) |
## 目录结构
```
universal-crawler/
├── app.py # Flask 主服务 (端口 16062)
├── engine.py # 爬虫引擎 (批量/自动/图片/重试/暂停恢复)
├── scheduler.py # 定时调度器 (间隔 + cron)
├── store.py # 任务/运行记录持久化 (JSON)
├── notify.py # 邮件通知
├── static/ # 前端管理界面
├── data/ # 运行时数据 (任务、运行记录、cookie)
├── out/ # 默认爬取输出
├── legacy/ # 原 tpu_crawler 脚本备份
└── start.sh # 启动脚本 (PID 文件管理)
```
## 注意事项
- 爬取前尊重目标站点 robots.txt / 使用条款,仅用于合法用途
- 延迟别设太低(建议 ≥1s),高频访问会被封 IP
- 每个任务独立的 cookie 文件,互不干扰;被反爬拦截时删除 `data/cookies_<任务ID>.json` 重新验证