edygert/bhindex
GitHub: edygert/bhindex
一个本地优先的 Black Hat 会议议程元数据采集与全文索引工具,通过 Wayback Machine 获取数据并存入 SQLite 供离线搜索。
Stars: 0 | Forks: 0
# bhindex
[](LICENSE)
[](https://www.python.org/)
本地优先的 **Black Hat** 大会议程元数据采集与索引工具。它将活动元数据抓取到本地 SQLite 数据库中,并提供全文搜索功能——**仅限元数据;它绝不会下载演示文稿或其他二进制文件。**
这是 **第 1 阶段(后端 + CLI)**。计划未来通过 TUI 和 FastAPI 层来封装相同的服务层(参见*架构**)。范围有意限制在 **2016 年及以后**(参见*覆盖范围*)。
## 为什么使用 Wayback Machine
`blackhat.com` 前端由 Cloudflare 托管挑战保护,会对数据中心 IP 上的非浏览器 HTTP 客户端返回 `403`。与其对抗它,bhindex 选择从 **Wayback Machine** 采集数据,它不在 Cloudflare 后面,并且可以在任何网络中工作(包括 CI)。由于过去的 Black Hat 活动是不可变的,存档中已经包含了基本上所有的历史元数据。
## 采集原理
- **近期活动(2016 年及以后)**发布了一个结构化的 JSON feed,地址为
`…//briefings/schedule/sessions.json`(议程页面本身是一个由此 feed 渲染的 Handlebars 模板)。bhindex 解析该 feed → 活动、议程、演讲者、摘要以及材料链接。
- **2016 和 2017 年的材料** *不* 包含在 feed 中。这些文件位于
`blackhat.com/docs//…/--.pdf`。bhindex 通过 Wayback CDX API 枚举它们,并通过将文件名与演讲者姓氏匹配(主要方式)以及标题 token 重叠(备选方式),将每个文件附加到其对应的议程中。非议程文件(调查、信件)将被跳过。
- **2018 年及以后的材料**直接来自 feed(`bh_files`,指向 `i.blackhat.com`)。
- **手动 / 离线**:您可以自己保存 `sessions.json`(或任何页面),并对其使用 `ingest-file`。
采集过程仅获取 HTML/JSON,并将材料 **URL** 记录为元数据。从采集过程不存在下载二进制文件的代码路径。
## 安装
需要 Python 3.12+ 和 [uv](https://docs.astral.sh/uv/)。
```
uv sync # install runtime + dev deps
uv run bhindex --help
```
## 用法
```
uv run bhindex init-db # create the database + FTS index
uv run bhindex harvest us-24 eu-23 asia-24 # harvest one or more editions (metadata only)
uv run bhindex harvest us-17 # 2017: materials backfilled from /docs automatically
# harvest 显示实时进度监视器以及每个事件的验证报告(异常 / 缺失数据)。
uv run bhindex stats # row counts + per-source/per-event coverage
uv run bhindex events # list harvested events
uv run bhindex search "kernel exploit" # full-text search; prints a #id per result
uv run bhindex show 1234 # full detail for one session (speakers, abstract, links)
# 离线 / 手动保存的页面:
uv run bhindex ingest-file ./sessions.json --url https://www.blackhat.com/us-24/briefings/schedule/sessions.json
```
版本的写法与它们在 URL 中显示的一样:`us-24`、`eu-23`、`asia-24`。
数据位于 `~/.local/share/bhindex/` 目录下(通过 `--data-dir` 或 `BHINDEX_DATA_DIR` 覆盖):
`bhindex.sqlite3`、`snapshots/`(用于调试和解析器测试的原始 HTML/JSON 捕获)和 `bhindex.log`。
**礼貌策略。** Wayback Machine 的速率限制非常严格,因此 bhindex 以 **5 秒的默认延迟 + 抖动**、一个在多次多版本运行中持续控制节奏的单一客户端,以及遵守 `429`/`5xx` 错误时 `Retry-After` 头部的指数退避策略来控制请求节奏(节流情况会在进度监视器中实时显示)。通过 `BHINDEX_REQUEST_DELAY`、`BHINDEX_MAX_RETRIES`、`BHINDEX_USER_AGENT`(或 `~/.config/bhindex/config.toml`)进行调整。在默认延迟下,完整的 2016–2025 年扫描(30 个版本)大约需要 10–12 分钟 —— 慢一点更友好。
## 架构
分层后端;依赖规则向内指向。CLI(以及未来的 TUI/FastAPI)**仅**调用服务层 —— 绝不直接调用 repositories、parsers 或 fetchers。
```
cli ─► services ─► parsers (recent feed parser, /docs materials matcher)
│ └─► adapters (HttpClient, WaybackFetcher, FileFetcher)
└─► storage (sqlite3 + FTS5, repositories, snapshots)
everything ─► core / dto (config, errors, urls, models; pydantic contracts)
```
- `ServiceContainer` 是 DI 的根;`HarvestService`、`SearchService`、`StatsService` 是公开的 API。
- 服务是**同步的**并且兼容 FastAPI:未来的 Web 层将构造相同的容器并调用相同的方法;TUI 从后台工作线程驱动它们。无需更改任何核心逻辑。
- Parsers 是纯函数(HTML/JSON + 基础 URL → DTOs);所有的网络 I/O 都位于 adapters 中。
## 覆盖范围(实际有效的内容)
| 年份 | 议程 + 演讲者 + 摘要 | 材料 |
|---|---|---|
| 2018–2025 (us/eu/asia) | ✅ feed | ✅ feed (`i.blackhat.com`) |
| 2016–2017 | ✅ feed | ✅ 从 `blackhat.com/docs/` 回填 |
| ≤2015 | ❌ 无 JSON feed | ❌ |
2016 年之前的旧版 `bh-media-archives` HTML 有意**排除在范围之外** —— 它的标记在不同年份之间差异太大,无法可靠解析,并且目前不需要。
## 开发
```
uv run pytest # unit + integration tests (fixtures are real, trimmed captures)
uv run ruff check . # lint
```
测试完全离线运行,针对 `tests/fixtures/` 中的测试夹具数据。集成测试套件固定了第 1 阶段的不变量,即采集仅写入元数据 + HTML 快照,绝不会写入二进制文件。
## 许可证
[MIT](LICENSE) © 2026 Evan H. Dygert.
bhindex 仅索引**元数据**(标题、摘要、演讲者和链接)。它不分发 Black Hat 演示文件;所有材料链接都指向其原始来源。在采集时,请尊重源站点的使用条款和 Internet Archive 的访问政策。
标签:Python, SQLite, 元数据管理, 全文搜索, 安全会议资料, 无后门, 逆向工具