hnvdie/noisu
GitHub: hnvdie/noisu
Noisu 是一款零依赖的 URL 结构分析与去重工具,通过模板指纹识别、硬过滤和模糊聚类,将大规模杂乱 URL 列表精简为结构上不同的干净端点集合。
Stars: 1 | Forks: 0
IDs / hashes / dates / versions / package versions → placeholders"] B --> C["Query Normalisation
strip tracking_param, sort + lowercase the rest"] C --> D{"Hard Filter
package: / ext: / general"} D -- match --> E[Dropped] D -- no match --> F[Group by template] F --> G{More than 1
URL in this template?} G -- no --> H[Keep as-is] G -- yes --> I["Fuzzy Cluster
MinHash + LSH near-dupe grouping"] I --> J[Keep first URL per cluster] H --> K["Apply --limit (per template)"] J --> K K --> L{--leaf enabled?} L -- yes --> M["Leaf Dedup
same domain + basename,
different directory depth"] L -- no --> N[Sort alphabetically] M --> N N --> O[Final clean URL list] E -.->|--dropped writes this instead| P[Dropped list] ``` | 阶段 | 目的 | |---|---| | 模板指纹识别 | 将可变路径段(哈希值、UUID、日期、版本号、不透明随机 ID、包构件)替换为占位符,使得结构相同的 URL 合并为一个模板。 | | Query 规范化 | 去除排除列表中定义的跟踪参数,并对剩余部分进行排序和转换为小写。仅作清理——其本身不会丢弃 URL。 | | 硬过滤 | 根据 `package:`、`ext:` 和扁平的 `general` 桶检查 URL。任何匹配都意味着 URL 被丢弃,没有例外。 | | 模糊去重 | 在一个模板组内,MinHash + LSH 聚类可以捕捉到仅靠结构化去重遗漏的近乎相同的 URL。每个聚类保留一个代表性 URL。 | | 叶子节点去重(可选,`--leaf`) | 第二次跨模板处理,捕捉在同一域名下不同目录深度中重复出现的相同文件名。默认关闭——启用前请参阅[完整参考](docs/reference.md)。 | 此 pipeline 始终运行。在其周围有两个独立的层: - **`--stats` / `--auto-dir-exclude`** —— 一个*仅报告*的目录级分析器,它无需任何固定的 regex 就能得知“这个目录实际上只是重复了数千次的 N 个模板”,因此你可以在手动编写排除规则之前发现垃圾目录。 - **`console.py`** —— 接收原始 URL 列表或 `--stats` CSV 并将其转化为实际的工作流(评分、过滤、导出、下钻、重新运行)。 ## 实战演示 输入 32 个杂乱的 URL,输出 10 个结构上不同的 URL —— 带有日期的报告、 随机 ID 的临时转储、带有版本的配置和跟踪参数全部自动合并或丢弃: ``` $ noisu -i demo_urls.txt -o demo_clean.txt --exclude-list all Pass 1 done. 19 URLs kept across 10 unique templates. Done. 10 URLs written to demo_clean.txt ``` | 之前 | 之后 | |---|---| | `.../reports/quarterly_2026-01-04.pdf`
`.../reports/quarterly_2026-02-01.pdf`
`.../reports/quarterly_2026-03-01.pdf`
`.../reports/quarterly_2026-04-05.pdf` | `.../reports/quarterly_2026-01-04.pdf` | | `.../config/settings_v1.2.3.json`
`.../config/settings_v1.2.4.json`
`.../config/settings_v1.3.0.json` | `.../config/settings_v1.2.3.json` | | `.../assets/logo.png`, `banner.jpg`, `icon.svg`, `roboto.woff2` | *(已丢弃 —— `ext:`)* | | `.../login?next=/dashboard&utm_source=newsletter&utm_medium=email` | `.../login?next=%2Fdashboard` | (完整的 32 个 URL 示例:[docs/reference.md#example](docs/reference.md#example)) ## 安装 ``` git clone https://github.com/HnvDie/noisu.git cd noisu pip3 install . ``` 这会在你的 `PATH` 中安装两个命令: | 命令 | 映射至 | 用途 | |---|---|---| | `noisu` | `noisu.py` 的清理/去重器 | 核心 pipeline:清理、去重、`--stats` | | `noisu-cli` | `console.py` 的决策支持层 | `analyze`、`stats`、`filter`、`export`、`drill`、`rerun` | ``` noisu -h noisu-cli -h noisu --version # prints the banner below + current version ``` 需要 Python 3.8+。两者都是零运行时依赖(仅限标准库)—— `pip3 install .` 只是配置好了 `noisu` / `noisu-cli` 命令,并将 `configs/*.lst` 配置文件作为包数据打包,它不会引入任何额外内容。如果你想为非常大的 `--stats` CSV 使用 `console.py` 的可选加速功能,`pip3 install ".[stats-fast]"` 会额外安装 polars/duckdb/pandas。 不想安装,只想从检出的代码库运行?这也可以: ``` python3 -m pip install -e . # editable install, same two commands # or, no install at all: python3 src/noisu/noisu.py -h python3 src/noisu/console.py -h ``` 每次运行 `noisu`/`noisu-cli --version` 都会打印: ``` _ (_) ____ ___ _ ___ _ _ | _ \ / _ \| |/___) | | | | | | | |_| | |___ | |_| | |_| |_|\___/|_(___/|____/ version: v1.0.1 ``` 该版本始终与 `pyproject.toml` 中的 `[project].version` 匹配——它是在运行时从已安装包的元数据中读取的,因此在升级版本并发布时,无需手动同步任何内容。 ## 项目结构 ``` noisu/ ├── pyproject.toml <- pip3 install . config; single source of truth for version ├── src/ │ └── noisu/ │ ├── __init__.py <- exposes __version__ (read from installed metadata) │ ├── noisu.py <- core cleaner/deduplicator (CLI entry point: `noisu`) │ ├── console.py <- analysis/decision-support layer (CLI entry point: `noisu-cli`) │ └── configs/ <- exclude-list profiles (.lst), see docs/reference.md │ ├── docs-cleaning.lst <- mirror/backup/dumps noise (default-ish profile) │ └── tracking-package-ext.lst <- tracking_param / package / ext rules, rarely changes ├── docs/ │ └── reference.md <- full CLI/console/exclude-list reference, examples ├── static/ <- project branding (banner, icons) ├── workspace/ <- created automatically by `console.py` (analyze --workspace / rerun) ├── LICENSE └── README.md ``` ## 快速入门 ``` # basic clean run - --exclude-list is required, no default profile noisu -i urls.txt -o clean.txt --exclude-list docs-cleaning noisu -i urls.txt -o clean.txt --exclude-list all cat urls.txt | noisu -o clean.txt --exclude-list docs-cleaning gau target.example | noisu --exclude-list docs-cleaning -o clean.txt # works the same piped straight out of a crawler - httpx (ProjectDiscovery), # katana, hakrawler, waybackurls, etc. - anything that writes one URL per line cat domains.txt | httpx -silent -follow-redirects | noisu --exclude-list docs-cleaning -o clean.txt # see what profiles are available before choosing one noisu --show-lst # find spam directories first, before writing any exclude rule noisu -i urls.txt --stats # feed report.csv into console.py for scoring / filtering / export noisu -i urls.txt --stats -o report.csv --export-format csv noisu-cli analyze report.csv noisu-cli export report.csv --confidence high --output configs/learned_spam.lst ``` 这涵盖了通用的端到端路径。 ## 完整参考 **[docs/reference.md](docs/reference.md)** 包含了全貌: - `noisu.py` 的每一个 flag(I/O、排除列表、去重调整、`--stats`、调试) - `--stats` 置信度评分的详细信息 - 每一个 `console.py` 子命令和过滤 flag - `.lst` 排除列表文件格式(`desc:`、`package:`、`ext:`、`tracking_param:`) - 一个包含输入/输出/原因的完整实操示例 你始终可以直接从工具本身获取权威且随时更新的 flag 列表: ``` noisu -h noisu-cli -h ``` ## 许可证 Noisu 基于 MIT 许可证发布——有关完整文本,请参阅 [`LICENSE`](LICENSE)。 ## ☕ 支持 如果你喜欢这个项目,请考虑支持它:
标签:Bug Bounty, Python, URL去重, 可自定义解析器, 文档结构分析, 无后门, 资产测绘, 逆向工具