在开源 OSINT 工具谱系中, qeeqbox 出品的 social-analyzer 是一个异常激进的存在:它把跨平台身份聚合这一原本属于专业调查员的脏活累活,封装成了一个普通人也能跑得起来的 Node.js 工具。仅凭一个用户名, 它就能在 999 个社交平台上并行扫描, 用 0-100 的置信度评分告诉你这个人是谁、在哪里、留下了哪些数字足迹。本文以工程视角深度拆解其 4 层级联检测、双引擎扫描架构、用户名排列组合关联算法以及 OCR 兜底机制, 探讨一个 OSINT 聚合器是如何把"分布式侦查"做成"单人可复现实验"的。
与一般爬虫教程不同, social-analyzer 真正值得研究的不是它能扫多少站点, 而是它在工程上对"概率匹配"和"身份聚类"两个抽象的落地方式。它把布尔式"存在/不存在"升级成 No/Maybe/Yes 三段评分, 又用用户名排列组合 + ixora 力导向图把碎片化的账号关联为一张可读的拓扑网络。这种设计哲学, 几乎可以作为所有跨平台聚合类工具的参考模板。
第 1 章 项目定位与全貌
social-analyzer 是 GitHub 上 qeeqbox 维护的一款跨 999 站点的开源 OSINT 身份聚合器, 仓库自我描述为: API, CLI, and Web App for analyzing and finding a person's profile in 1000 social media websites。它有三种交付形态: 暴露 HTTP 接口的 API 模式、命令行直接调用的 CLI 模式、以及带可视化界面的 Web App 模式, 三者共享同一套扫描内核。
技术栈层面, 项目是 Node.js 生态的典型组合拳: Selenium 驱动无头浏览器处理 SPA 重度站点, tesseract.js 提供 OCR 截图识别能力, cheerio 负责服务端 HTML 解析, ixora 渲染力导向图, franc 做多语种检测, 整套链条跑在 Express 暴露的 REST 接口之上, 既适合研究者本地调试, 也适合集成进更大的情报流水线。
为什么它重要
OSINT 领域的工具长期两极分化: 商业平台昂贵且封闭, 而零散脚本又难以复用。social-analyzer 的价值在于以 AGPL-3.0 强 copyleft 协议提供了一个可审计、可二次开发、可自托管的中点方案, 这在隐私合规日趋收紧的当下尤为关键。
第 2 章 核心架构:4 层检测 + 双引擎
social-analyzer 的核心设计可以浓缩为两条主线: 一条是4 层级联检测, 一条是fast-scan 与 slow-scan 双引擎。前者负责"用什么规则去判定命中", 后者负责"用什么样的网络姿态去拿数据", 两者在 engine.js 中被统一调度。
4 层检测机制
检测层由广到深依次为: normal(1224) / shared(389) / advanced(205) / special(3)。normal 层覆盖绝大多数标准静态站点, 用最朴素的字符串包含判定; shared 层把多个站点共用的指纹抽出来, 减少重复探测; advanced 层针对反爬较强的站点做更深度的 HTML 切片; special 层只有 3 个站点, 专门留给 Facebook / Google / Gmail 这类重度 SPA 页面, 因为它们的 DOM 必须靠浏览器执行 JS 才能拿到。
双引擎扫描架构
fast-scan.js 是纯 HTTP 并行扫描, 默认并发 15, 配合 3 轮重试 + 最终失败归类, 用 uuid + global_lock 防止重复扫描同一目标。slow-scan.js 则调用 Selenium 启动无头浏览器, 速度慢但能渲染 JS, 是 special 检测的必由之路。两者并非互斥, 而是一个站点先走 fast, 命中失败或属于 special 列表才升级到 slow。
// engine.js: 调度检测层与扫描引擎
const scanTarget = async (site, username) => {
let result = await fastScan(site, username); // fast-scan.js
if (!result.matched && site.detection === 'special') {
result = await slowScan(site, username); // slow-scan.js
}
if (site.detection === 'ocr') {
const text = await ocrScan(site, username); // tesseract.js
result = updateByOCR(result, text);
}
return scoreResult(result); // 0-100 置信度
};第 3 章 评分机制与输出
不同于大多数爬虫直接返回布尔命中, social-analyzer 引入了 0-100 置信度评分, 划分为 No(0-30) / Maybe(31-70) / Yes(71-100) 三段。评分函数综合多层检测的命中证据, 例如 normal 命中一次 +10, shared 命中一次 +25, special 命中一次 +40, 上限封顶 100。
JSON 结构化输出
每次扫描的最终结果是结构化 JSON 数组, 每条记录包含 platform、url、detection、status、score 字段, 既能直接喂给前端 ixora 渲染, 也方便下游脚本做二次过滤。这种"概率 + 证据链"的设计比单一布尔更接近 OSINT 真实场景, 因为侦查员要的从来不是"是/否", 而是"有多大把握"。
ixora 力导向图可视化
ixora 库把 999 站点 + 跨账号关联关系渲染成 Force-directed Graph, 节点是平台账号, 边是算法判定出的同源关系。一个身份簇在图中自然聚成一个团, 让人一眼看出"哪些账号背后可能是同一个人", 这是从"列表"升级到"网络"的关键一步。
第 4 章 多账号关联算法
OSINT 真正的难点不是"找到账号", 而是"判定这些账号属于同一人"。social-analyzer 的做法是 用户名排列与组合(permutations and combinations): 把输入的 'zhangsan' 自动扩展为 'zhangsan_88' / 'zhangsan.bj' / 'zhangsan666' 等变体, 再对每个变体独立扫描, 把所有命中节点在图中以边相连。
变体生成策略
变体不是随机字符串, 而是基于常见命名习惯的下划线后缀、点号分隔、数字尾缀、缩写前缀等有限集合。这种"启发式 + 穷举"的折中, 既控制了请求数爆炸, 又覆盖了主流变体模式。配合扫描结果的置信度, 算法会对同一身份簇内的节点加权, 在图中让强关联的节点距离更近。
// 用户名变体生成器
const generateVariants = (name) => {
const suffixes = ['', '_', '.', '88', '666', 'bj', 'real', 'pro'];
const variants = new Set([name]);
suffixes.forEach(s => variants.add(name + s));
return Array.from(variants);
};第 5 章 反爬突破与特殊场景
当目标平台的 profile 只剩图像, 或者核心信息被验证码/前端渲染吃掉, 传统 HTTP + cheerio 路径直接失效。social-analyzer 的解法是 OCR 兜底: slow-scan 启动 Selenium 截图后, 调用 tesseract.js 提取像素中的文本, 再走一遍匹配流程。这相当于把"像素就是新文本"作为最后一道防线。
special 检测层专攻 SPA
Facebook、Google、Gmail 这三家页面重度依赖 JS 渲染, 普通 GET 只能拿到空壳 HTML, 必须靠 Selenium 真正执行 JS 才能拿到 DOM 文本。special 检测层只有 3 个站点, 但它们消耗的资源和时间往往是其他站点的几十倍, 这也是为什么必须独立分层而不是塞进 advanced 层。
shared_detections 复用机制
有些社交平台使用同一套前端模板, 比如 FriendTech 系列, 它们的 DOM 指纹高度相似。social-analyzer 把这些指纹抽出为 shared_detections, 一次模板探测可复用到多个站点, 既降低重复请求, 又减少被风控系统察觉的概率。
第 6 章 局限、伦理与生态
999 站点看着壮观, 但文化覆盖并不均衡: 中文平台仅有豆瓣和知乎两家在册, 微博、B 站、小红书、抖音等主流社区全部缺席。这意味着查询 '张三' 这类中文用户名, 主要返回的是英文/小语种结果, 对中文 OSINT 工作流而言远远不够, 实际部署时必须自建站点池补充。
许可证层面, 项目选择 AGPL-3.0 强 copyleft 协议, 派生作品必须开源。这一定位既传播了工具, 也防止其被私有化包装成商业监控产品, 在 OSINT 领域是一种少见的开放但克制的治理姿态。然而, 强 copyleft 也是双刃剑: 企业内部集成时往往因合规问题放弃, 这限制了它在 B 端的传播速度。
截至目前, 该项目在 GitHub 积累了约 23k stars 与活跃的 issue 讨论, 这种社区规模本身就说明 OSINT 工具的公共化是一条可行路径。但 stars 越多、责任越大, 维护者需要持续更新站点指纹、对抗反爬升级、并拒绝将其武器化——这种社区治理与法律伦理的平衡, 比任何一段核心代码都更难维护。
结论
social-analyzer 给所有跨平台聚合类工具提供了一个可参考的工程范式: 用 4 层级联检测 拆解判定难度, 用 fast/slow 双引擎 平衡速度与拟真度, 用 0-100 置信度 替代布尔, 用 用户名排列组合 实现身份聚类, 再用 ixora 力导向图 把数据点变回可读的关系网络。它的价值不在于"能扫多少站", 而在于把 OSINT 这一模糊领域, 用工程语言重新表述为可度量、可复现、可治理的流水线。
对于中文使用者而言, 它的最大启示反而是负向的: 任何想真正落地的本地化 OSINT 工具, 都必须自建一份持续维护的中文站点指纹库, 并设计自己的关联算法与可视化层。social-analyzer 是优秀的脚手架, 但绝不是终点。