bitdruid/grove

GitHub: bitdruid/grove

Grove 是一个基于 Flask 和 Celery 的自包含网页抓取运行器,支持对域名执行自动化信息收集 pipeline 并通过 Web UI 展示结果。

Stars: 0 | Forks: 0

# Grove **抓取那些 DOM 树!** [![Docker Pulls](https://img.shields.io/docker/pulls/bitdruid/grove?logo=docker&logoColor=white&label=pulls)](https://hub.docker.com/r/bitdruid/grove) ![Python](https://img.shields.io/badge/python-3.13-3776AB?logo=python&logoColor=white) ![Flask](https://img.shields.io/badge/Flask-black?logo=flask&logoColor=white) ![Celery](https://img.shields.io/badge/Celery-37814A?logo=celery&logoColor=white) ![Redis](https://img.shields.io/badge/Redis-DC382D?logo=redis&logoColor=white) ![SQLite](https://img.shields.io/badge/SQLite-07405E?logo=sqlite&logoColor=white) ![Bootstrap](https://img.shields.io/badge/Bootstrap-7952B3?logo=bootstrap&logoColor=white) [关于](#about) • [功能](#what-it-does) • [快速开始](#quick-start) • [技术栈](#stack) • [环境](#environment) • [卷与持久化](#volumes--persistence) • [本地开发](#local-dev) • [依赖项](#dependencies)
## 关于 在过去一份已经放弃的工作中,我们曾使用过一个由同事编写的、后来被废弃的 php7 网页抓取工具。离职后,我决定重拾这个想法——首先将其升级到 php8。有趣的是:这促使了 [pywaybackup](https://github.com/bitdruid/python-wayback-machine-downloader) 的开发,它最初是以 [wayback-machine-downloader](https://github.com/hartator/wayback-machine-downloader) 的原始状态被使用的(感谢这个伟大的项目 - o7)。后来我决定再次用 Python 重写这个抓取工具的思路。这段代码其实已经在我的电脑里闲置好几年了。过去几周里我把它修整好以便部署。这只是一个“纯属娱乐”的项目。 所以,无视它或者使用它——我都不介意。不过,如果有人喜欢它并希望增加某些功能,我也很乐意帮忙。 这个在 Docker 中运行的项目专为部署而设计,无需堆叠任何其他服务——一切均已包含在内。只需构建并运行即可。 ## 功能 OSINT 风格的网页抓取任务运行器。提交一个 URL,它就会运行一个 pipeline(域名查询、DNS、geoip、子域名、源码下载、Wayback 存档、截图、OCR、邮件提取),然后通过浏览器 UI 展示结果: - **域名与网络情报** — 域名/IP whois + 查询,DNS A/AAAA 记录, geoip,子域名枚举。 - **内容下载** — 页面源码(`wget`)和 Wayback Machine 存档 快照;提取超链接、meta 标签、外部链接和电子邮件 地址;全页截图(+ PDF)。 - **文件分析** — 对下载的图片和 PDF 进行 OCR;从图片、音频、视频和文档中提取 EXIF 元数据 (如果存在,包括 GPS 坐标)。 - **浏览** — 每个作业的结果页面将所有发现归类到可折叠的 各个部分中,并在作业运行时提供实时日志流。 - **搜索** — 对*所有*作业下载的文件进行全文搜索;每个命中结果 都会显示高亮的代码片段,并打开一个带有语法高亮的文件查看器, 标记并滚动到匹配位置。 - **离线导出** — 为每个作业下载一个自包含的 ZIP 文件(静态结果 页面 + 所有下载的文件),以便在脱离服务器的情况下保留或分享。 ## 快速开始 ``` docker compose up --build ``` - Web UI → http://localhost:5000 - DB browser (sqlite-web) → http://localhost:5001 *(通过 `compose.yml` 中的 `SQLITE_WEB=1` 启用)* 一个自包含镜像:Redis、Celery worker 和 Web 进程都 在 `tini` 下的入口点启动。无需设置任何外部服务。 ## 技术栈 - **Flask** + **Flask-SocketIO** — Web UI 和 WebSocket/实时日志传输。 - **Celery** + **Redis** — 任务队列;链中的每个工具代表一个任务。 取消任务 = `AsyncResult.revoke(terminate=True)`。 - **SQLite** — 单个文件位于 `instance/db.sqlite3`(schema 自动创建)。 - **Whoosh** — 位于 `jobs//meta/index/` 下,为每个作业提供全文索引。 ## 环境 Redis 的配置(`REDIS_URL`、`CELERY_*`、`SOCKETIO_MESSAGE_QUEUE`)已内置在 镜像中,并指向嵌入式 broker —— 无需手动设置。只有在你想使用外部 Redis 时,才需要将 `CELERY_BROKER_URL` 指向非 localhost 地址。 面向用户的开关(在 `compose.yml` 中设置): | 变量 | 默认值 | 用途 | | ------------------ | ------- | ------------------------------------------------------ | | `ENABLE_PROXY_FIX` | `1` | 如果不在代理后面则设为 `0`。用于处理 `X-Forwarded-*` header | | `SQLITE_WEB` | `1` | 设为 `0` 可禁用 sqlite-web db browser | | `SQLITE_WEB_PORT` | `5001` | db browser 的端口 | 反向代理 / 子路径设置:参见 [nginx.example.conf](nginx.example.conf)。 ## 卷与持久化 **默认情况下不挂载任何内容** —— 镜像是自包含的,因此作业的 生成物和数据库都存在于容器的可写层中,并且**会在 执行 `docker rm` 时丢失**。取消注释 `compose.yml` 中的 `volumes:` 块即可持久化它们。 | 容器路径 | 包含内容 | | --------------- | ------------------------------------------------------------------------------------------ | | `/app/jobs` | 每个作业的生成物:source-code、screenshots、zip、`meta/`(search index + Wayback csv/db)。 | | `/app/instance` | SQLite DB (`db.sqlite3`) + 轮换日志 (`grove.log`)。 | 请将两者**放在一起**保留 —— 数据库通过路径引用作业文件,因此如果清除其中一个 而保留另一个,就会产生孤立的记录。设置 → **Prune App** 会一致地清除 这两者(**Prune Log** 仅清除日志表)。 ## 本地开发 `start.sh` 是开发环境的入口点:它会检查系统依赖,创建 `.venv`,安装 Python 依赖,将 Redis 作为 daemon 启动,运行 Celery worker,并在 前台启动 Web 进程。 ``` ./start.sh ``` 需要 Python 3.13 以及用于安装系统软件包的 `pacman` 或 `apt`。之后使用 `redis-cli shutdown` 停止开发环境的 Redis。 ## 依赖项 - `requirements.txt` — 顶层依赖,宽松的版本要求(由人工维护)。 - `requirements.lock` — 完整的 `pip freeze`,已锁定版本。**镜像从此 文件**进行安装,以确保构建的可重复性。 要升级依赖:请编辑 `requirements.txt`,然后重新生成 lock 文件,以便构建过程能够应用这些更改 — ``` ./start.sh # or: pip install -r requirements.txt --upgrade ./lock_new_requirements.sh --container grove # freeze from a running container ./lock_new_requirements.sh --venv .venv # ...or from a local venv # 同时提交 requirements.txt 和 requirements.lock ``` `torch`(由 `easyocr` 用于 OCR 拉取)通过 `requirements.txt` 中的 `--extra-index-url` header 解析为其 **CPU** 版本 —— `+cpu` wheel 的优先级高于 PyPI 的 CUDA 版本,因此不需要数 GB 的 CUDA 依赖(这使镜像体积保持在约 4 GB,而不是 约 11 GB)。OCR 在后台 worker 中运行,因此 CPU 绰绰有余。若要使用 GPU,请删除该 `--extra-index-url` 行,并启用 `compose.yml` 中的 nvidia 块。
标签:Docker, Flask, Python, TCP SYN 扫描, Web UI, Web爬虫, 命令控制, 安全防御评估, 搜索引擎查询, 数据采集, 无后门, 请求拦截, 逆向工具