TrippyEngineer/face-osint
GitHub: TrippyEngineer/face-osint
利用人脸特征在多个开源平台并行搜索并验证身份的身份解析系统。
Stars: 0 | Forks: 0
# 人脸 OSINT
**捕捉人脸,获取身份。**
将摄像头对准某人、上传照片或从手机进行直播 —
Face OSINT 同时搜索 10+ 个开源情报来源,
对人脸验证每个结果,并在两分钟内提供排名去重后的身份档案。
[](https://python.org)
[](https://flask.palletsprojects.com)
[](https://github.com/serengil/deepface)
[](https://sqlite.org)
[](#负责任使用)
**无需 Docker。无需 Redis。无需云账户。无需 API 密钥即可启动。**
通过单个 `pip install` 命令即可在本地机器上完全运行。
## 流程概览
```
flowchart TD
INPUT(["`**Input**
📷 Camera · 🖼 Photo · 📡 WiFi Cam`"])
EMB["`**Layer 1 — Embedding**
DeepFace · Facenet512
512-D L2-normalised vector`"]
DB[("`**SQLite WAL**
Face vectors
Search history`")]
SCRAPE["`**Layer 2 — Parallel Scraping**
7 scrapers · ThreadPoolExecutor
Each with isolated deadline cap`"]
S1["`🔍 reverse_face
Yandex · SerpApi · CSE
_90 s_`"]
S2["`🔎 search_engines
Google CSE · DDG · Bing
_25 s_`"]
S3["`🎓 academic
Scholar · OpenAlex · ORCID
_35 s_`"]
S4["`💻 github
Public API · no auth
_20 s_`"]
S5["`🗨 reddit
PRAW · JSON fallback
_15 s_`"]
S6["`🗂 passive
Wayback · GDELT · crt.sh
_20 s_`"]
S7["`🕵 username
125 direct + Sherlock 300+
_50 s_`"]
MATCH["`**Layer 3 — Face Matching**
Download · embed · cosine compare
face_score set on every candidate`"]
SCORE["`**Layer 4 — Weighted Scoring**
70% face · 10% name · 18% meta
Cosine thresholds: CONFIRMED / POSSIBLE / REJECTED`"]
RESOLVE["`**Layer 5 — Entity Resolution**
Union-Find identity graph
Edge weights by signal type`"]
OUT["`**Output**
📄 info.txt · 📊 JSON · 🖼 Photos · 🗄 SQLite`"]
INPUT --> EMB
EMB <--> DB
EMB --> SCRAPE
SCRAPE --> S1 & S2 & S3 & S4 & S5 & S6 & S7
S1 & S2 & S3 & S4 & S5 & S6 & S7 --> MATCH
MATCH --> SCORE
SCORE --> RESOLVE
RESOLVE --> OUT
style INPUT fill:#1e293b,stroke:#38bdf8,color:#f1f5f9
style EMB fill:#1e3a5f,stroke:#60a5fa,color:#f1f5f9
style DB fill:#1c2a1e,stroke:#4ade80,color:#f1f5f9
style SCRAPE fill:#2d1b4e,stroke:#a78bfa,color:#f1f5f9
style S1 fill:#1a2535,stroke:#f472b6,color:#f1f5f9
style S2 fill:#1a2535,stroke:#f472b6,color:#f1f5f9
style S3 fill:#1a2535,stroke:#f472b6,color:#f1f5f9
style S4 fill:#1a2535,stroke:#f472b6,color:#f1f5f9
style S5 fill:#1a2535,stroke:#f472b6,color:#f1f5f9
style S6 fill:#1a2535,stroke:#f472b6,color:#f1f5f9
style S7 fill:#1a2535,stroke:#f472b6,color:#f1f5f9
style MATCH fill:#1e3a5f,stroke:#60a5fa,color:#f1f5f9
style SCORE fill:#3b1f1f,stroke:#fb923c,color:#f1f5f9
style RESOLVE fill:#1c2a1e,stroke:#4ade80,color:#f1f5f9
style OUT fill:#1e293b,stroke:#38bdf8,color:#f1f5f9
```
## 架构设计
```
graph TB
subgraph ENTRY["Entry Points"]
APP["`**app.py**
Flask + SSE
Browser camera / upload`"]
MAIN["`**main.py**
OpenCV display loop
Local webcam only`"]
end
subgraph L1["Layer 1 — Embedding · embedding.py"]
EMBED["`DeepFace.represent()
Model: Facenet512
Detector: opencv | Align: true
Threshold: 0.50 | Output: 512-D vector`"]
end
subgraph L2["Layer 2 — Persistence · storage/database.py"]
DB[("`SQLite WAL
searches · matches
face_vectors`")]
end
subgraph L3["Layer 3 — Parallel Scraping · scrapers/"]
direction LR
RF["`reverse_face.py
Yandex · SerpApi Lens
Google CSE · 4 engines
Top 25 face-verified`"]
SE["`search_engines.py
Google CSE → DDG → Bing
LinkedIn-first cascade
10 social platforms`"]
AC["`academic.py
Semantic Scholar
OpenAlex · ORCID
1-hr cache · dedup`"]
GH["`github · reddit
GitHub public API
PRAW / JSON fallback`"]
PA["`passive.py
Wayback · GDELT
crt.sh · PGP servers
Gravatar`"]
UN["`username.py
125 direct checks
+ Sherlock 300+ (15 s cap)
socid-extractor`"]
end
subgraph L4["Layer 4 — Face Matching · aggregator/face_matcher.py"]
FM["`URL-deduplicated download cache
Parallel embedding extraction
Sets face_score · face_similarity
face_verified on every match`"]
end
subgraph L5["Layer 5 — Scoring · aggregator/scorer.py"]
SC["`combined = 0.70·face + 0.10·name
+ 0.08·social + 0.05·photo
+ 0.07·sources
≥ 0.68 → CONFIRMED | 0.50–0.68 → POSSIBLE
< 0.35 → REJECTED`"]
end
subgraph L6["Layer 6 — Entity Resolution · aggregator/resolver.py"]
RES["`Union-Find identity graph
face-match 1.0 | email 0.90
username 0.85 | company 0.45
name 0.40 | location 0.30`"]
end
subgraph OUT["Output · storage/folder_writer.py"]
direction LR
TXT[info.txt]
JSON[matches_summary.json]
PHOTOS[scraped_photos/]
SQLOUT[(face_osint.db)]
end
APP & MAIN --> L1
L1 <--> L2
L1 --> L3
RF & SE & AC & GH & PA & UN --> L4
L4 --> L5
L5 --> L6
L6 --> OUT
```
## 快速开始
```
# 需要 Python 3.10 或 3.11(3.12 会导致 TensorFlow 2.16 出现问题)
pip install -r requirements.txt
cp .env.example .env # all keys optional — works without any
python diagnose.py # health check: packages, keys, network
python app.py # web UI — browser opens automatically
```
## 判决系统
```
graph LR
A[Combined Score] --> B{Threshold}
B -->|≥ 0.85| C["🟢 CONFIRMED (high)\nFace verified · consistent metadata"]
B -->|≥ 0.70| D["🟡 CONFIRMED (low)\nFace verified · limited metadata"]
B -->|≥ 0.55| E["🟠 POSSIBLE\nNear-match face OR strong metadata"]
B -->|< 0.55| F["🔴 UNLIKELY\nName match only · no photo evidence"]
style C fill:#14532d,stroke:#4ade80,color:#f1f5f9
style D fill:#1a3a1a,stroke:#86efac,color:#f1f5f9
style E fill:#431407,stroke:#fb923c,color:#f1f5f9
style F fill:#3b0a0a,stroke:#f87171,color:#f1f5f9
```
## 输入模式
| 模式 | 使用方法 |
|---|---|
| **浏览器摄像头** | 点击 Camera(摄像头)标签 → 允许浏览器访问 → 点击 Capture(拍摄)|
| **文件上传** | 拖放或选择任意 JPEG / PNG / WebP 文件 |
| **WiFi / IP 摄像头** | 安装 [IP Webcam](https://play.google.com/store/apps/details?id=com.pas.webcam)(安卓版)· 点击 Start server(启动服务器)→ 在 WiFi Cam 标签中输入 `IP:8080` |
| **姓名提示** | 在姓名字段中添加上下文:`John Smith | New York @ Acme Corp` |
**姓名提示语法:**
```
John Smith | New York ← location context
John Smith @ Acme Corp ← employer context
John Smith | New York @ Acme Corp ← both
```
## 爬虫参考
| 爬虫 | 超时时间 | 数据源 | 备注 |
|---|---|---|---|
| `reverse_face` | 90 秒 | Yandex · SerpApi Lens · Google CSE | 4 个引擎并行 · 人脸验证前 25 个结果 |
| `search_engines` | 25 秒 | Google CSE → DDG → Bing | LinkedIn 优先 · 10 个社交平台 |
| `academic` | 35 秒 | Semantic Scholar · OpenAlex · ORCID | 1 小时缓存 · 按用户 ID 去重 |
| `github` | 20 秒 | GitHub 公共 API | 有令牌 5,000 请求/小时 · 无令牌 60/小时 |
| `reddit` | 15 秒 | PRAW · 公共 JSON 备用 | 无需认证 |
| `passive` | 20 秒 | Wayback · GDELT · crt.sh · PGP · Gravatar | 证书透明度 + 密钥服务器 |
| `username` | 50 秒 | 125 个直接平台检查 | + Sherlock 300+(15 秒内部限制)|
## API 密钥
所有密钥均为可选。系统可在无需配置的情况下使用约 8 个免费数据源。
复制 `.env.example` → `.env` 并填写您已有的密钥。
| 密钥 | 获取位置 | 免费额度 | 解锁功能 |
|---|---|---|---|
| `GOOGLE_CSE_KEY` + `GOOGLE_CSE_ID` | [programmablesearchengine.google.com](https://programmablesearchengine.google.com) | 100 请求/天 | 最佳 LinkedIn + 社交搜索 |
| `SERPAPI_KEY` | [serpapi.com](https://serpapi.com) | 100 请求/月 | Google Lens + Yandex 人脸搜索 |
| `IMGBB_API_KEY` | [imgbb.com/api](https://imgbb.com) | 免费 | SerpApi 上传的图像托管 |
| `GITHUB_TOKEN` | GitHub → Settings → Developer tokens | 免费 | 5,000 请求/小时(对比未认证的 60/小时)|
| `GITLAB_TOKEN` | GitLab → Profile → Access Tokens | 免费 | GitLab 用户搜索(2024 年起必需)|
| `BING_API_KEY` | Azure → Bing Search v7 | 1,000 请求/月 | Bing 网页 + 视觉搜索 |
| `BRAVE_API_KEY` | [api.search.brave.com](https://api.search.brave.com) | 2,000 请求/月 | Brave Search 结果 |
| `HUNTER_API_KEY` | [hunter.io/api-keys](https://hunter.io/api-keys) | 25 请求/月 | 邮件情报 |
| `REDDIT_CLIENT_ID` + `SECRET` | reddit.com/prefs/apps | 免费 | 已认证的 Reddit API |
| `OPENALEX_MAILTO` | 任意邮箱地址 | 免费 | OpenAlex 礼貌池(更高速率限制)|
```
python diagnose.py # see which keys are active and test connectivity
```
## 输出结构
```
data/output/
└── John_Doe_20260404_1430_a1b2c3d4/
├── captured_photo.jpg original camera frame
├── face_crop.jpg 160×160 aligned face crop (Facenet512 input)
├── info.txt human-readable plaintext report
├── matches_summary.json full structured data — all scores + metadata
└── scraped_photos/
├── github_johndoe_a1b2.jpg
├── reverse_face_yandex_c3d4.jpg
└── ...
```
搜索历史和人脸向量保存在 `data/face_osint.db`(SQLite WAL 模式)。
## CLI 界面
```
python main.py # OpenCV window — click the window first to capture keystrokes
```
| 按键 | 操作 |
|---|---| |
| `SPACE` | 冻结画面 → 输入姓名 → 开始完整 OSINT 搜索 |
| `F` | 翻转/镜像摄像头画面 |
| `D` | 诊断 — 打印与所有存储的人脸向量的余弦距离 |
| `H` | 切换 HUD 叠加层 |
| `Q` | 退出 |
## 技术栈
| 组件 | 库 | 原因 |
|---|---|---|
| 人脸嵌入 | [DeepFace](https://github.com/serengil/deepface) + Facenet512 | 512 维 L2 归一化向量,ArcFace 级精度 |
| Web UI | Flask + Server-Sent Events | 零安装,实时进度推送 |
| 摄像头 | OpenCV (`cv2`) | 原生 Windows 网络摄像头 + MJPEG WiFi 串流 |
| 持久化 | SQLite(WAL 模式) | 单文件,零配置,线程安全 |
| HTML 解析 | BeautifulSoup + lxml | 快速、宽容地抓取搜索结果 |
| 姓名匹配 | rapidfuzz | 模糊字符串评分,用于实体解析 |
| 用户名 OSINT | [Sherlock](https://github.com/sherlock-project/sherlock) + 直接检查 | 300+ 个平台 |
**设计约束:** 单进程 · 无 Celery / Redis / Docker / PostgreSQL · 守护线程 + `ThreadPoolExecutor` · 所有共享状态置于 `threading.Lock` 后。
## 环境要求
- Python **3.10** 或 **3.11** — TensorFlow 2.16 不支持 3.12
- 约 600 MB 磁盘空间用于 Facenet512 模型权重(首次运行时下载一次)
- 网络摄像头、WiFi 摄像头或文件上传
```
pip install -r requirements.txt
```
可选增强以获得更好覆盖率:
```
pip install sherlock-project # username scraper (300+ platforms)
pip install socid-extractor # social ID extraction
pip install praw # authenticated Reddit API
```
## 故障排除
| 症状 | 解决方法 |
|---|---|
| **"未检测到人脸"** | 人脸必须占据画面 ≥ 20% · 避免背光 · 靠近一些 |
| **常见姓名返回 `no_results`** | 添加上下文:`John Smith | London` 或 `John Smith @ Google` |
| **搜索耗时约 90 秒** | 属于正常情况 — `reverse_face` 会下载并人脸验证最多 25 张候选照片 |
| **TensorFlow 导入错误** | 使用 Python 3.10 或 3.11 — TF 2.16 不支持 3.12 |
| **LinkedIn 始终返回 0 结果** | 在 `.env` 中设置 `GOOGLE_CSE_KEY` + `GOOGLE_CSE_ID` |
| **WiFi 摄像头无法连接** | 手机和电脑必须在同一子网 · 先在浏览器中测试 `http://IP:8080/video` |
```
python diagnose.py # end-to-end health check with targeted fix instructions
```
## 数据与隐私
所有数据都保留在您的本地机器上 — 无遥测,无云同步。
| 路径 | 内容 |
|---|---|
| `data/face_osint.db` | 搜索历史、匹配记录、512 维人脸向量 |
| `data/output/` | 每次搜索的文件夹:照片、报告、JSON |
| `data/models/` | DeepFace 模型权重(约 600 MB,下载一次)|
| `logs/` | 轮转日志,10 MB × 5 个文件 |
要清除所有搜索数据:删除 `data/face_osint.db` 和 `data/output/`。
该工具不会向除上述爬虫数据源之外的任何外部地址发起连接请求。
## 负责任使用
此工具专为**合法的 OSINT 研究**而构建 — 验证身份、失踪人员、调查欺诈、学术研究,以及在获得明确授权的情况下进行渗透测试。
请勿将其用于跟踪、骚扰或未经授权构建私人个人信息档案。
请遵守您所在司法管辖区的适用法律。尊重各平台的服务条款。标签:DeepFace, ESC4, ESC8, Facenet512, Flask, GDELT, GitHub搜索, OSINT, Python, Reddit, Splunk, SQLite, ThreadPoolExecutor, Wayback Machine, 人脸搜索, 人脸识别, 人脸验证, 反向图像搜索, 反汇编, 向量检索, 图像嵌入, 多模态融合, 威胁情报, 学术搜索, 实时处理, 密码管理, 并行爬取, 开发者工具, 搜索引擎, 数字取证, 数据泄露, 无后门, 本地运行, 社会工程学, 网络安全, 自动化脚本, 身份解析, 身份识别, 逆向工具, 隐私保护