news 2026/10/20 2:40:39

freehire 数据全景:225 个来源、92 个 ATS 平台、29.4 万家公司的数据版图是怎么搭起来的

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
freehire 数据全景:225 个来源、92 个 ATS 平台、29.4 万家公司的数据版图是怎么搭起来的

【免费下载链接】freehire

freehire — the open-source search engine for job seekers

项目地址:https://gitcode.com/gh_mirrors/fr/freehire
点击查看免费下载

freehire 是一个开源的招聘搜索引擎,它的核心能力在于把分散在全球各地的招聘信息汇成一张可搜索、可筛选的统一版图:截至最新目录快照,freehire 从225 个数据源中抓取了330 万+ 条在招职位,覆盖29.4 万家公司,其中92 个 ATS 平台(Applicant Tracking System,招聘管理系统)贡献了绝对大头。这篇文章带你用 10 分钟看懂这张数据版图的分层结构、抓取调度机制,以及那些对外公布的数字是如何保持准确的。

上图是项目对外展示的数据概览卡片(卡片数字为较早一次快照,本文以最新目录快照为准)。

职位数据分三层:ATS 平台、聚合站、企业官网

freehire 把所有数据源归为三种类型,这个分类不是人工维护的配置,而是直接由适配器的 Go 类型推导出来的,定义逻辑位于 internal/ingest/sources/ 包中。每层的规模如下(完整清单见 docs/sources.md):

层级数量覆盖公司在招职位
🏢 ATS 平台92 个157,3992,644,796
🌐 聚合站与招聘板100 个172,884629,571
🏷️ 企业招聘官网30 个5926,222

注意:同一家公司可能同时出现在多个来源下,所以各层公司数相加会大于 29.4 万这个去重后的总数。

ATS 平台:真正的数据主力

92 个 ATS 平台贡献了近 264 万条在招职位,占全库的 80%。几个头部玩家的数据量级感受一下:

  • workday:4,202 家公司,74.8 万条职位(单一平台最大)
  • trudvsem:7.0 万家公司的长尾覆盖王,26.7 万条职位
  • smartrecruiters / oracle / greenhouse:各自 15 万~22 万条职位

长尾同样惊人:从 phenom 到只有 1 家公司的 epam,最末位的数据源也稳定产出。每个 ATS 平台对应 internal/ingest/sources/ 下一个独立适配器文件(如workday.go、greenhouse.go),全部实现同一个Source接口,所以新平台接入的工作量是有界的。

聚合站与企业官网:补充覆盖与一手数据

聚合站(Adzuna、hh、whatjobs 系列、Telegram 频道等 100 个来源)价值在于覆盖面广,其中 whatjobs 一个系列就分拆出 40 多个国家/地区站点。而 30 个企业招聘官网来源则是"一手数据":Amazon 单家 7,680 条、Apple 4,268 条、Google 3,452 条职位直接来自公司自己的招聘页面,绕过了任何中间商。

抓取调度:一次一平台的单程工模式

freehire 的抓取不是"一个常驻爬虫进程跑所有平台",而是run-once-and-exit worker(运行一次即退出)模型,调度入口在 cmd/ingest/main.go:

  1. 每次运行只处理一个平台——比如这一次跑greenhouse、下一次跑lever,各平台按自己的节奏独立调度,慢平台永远不阻塞快平台。
  2. 数据源目录是纯数据——boards表每行对应"某公司在某 ATS 平台上的某个看板"(provider + board + region),建表语句见 migrations/0123_boards.sql,调度周期配置见 migrations/0132_ingest_schedule.sql。
  3. 统一流水线——每次运行把抓到的原始页面交给 internal/ingest/pipeline/pipeline.go 中的pipeline.Runner:抓取 → 归一化成单一 schema → 去重 → 写入数据库。
  4. 失败有冷却——某个看板持续失败会进入记录的冷却期,而不是每次运行都反复重试。

这种设计的妙处:worker 之间不共享内存,所有协调都落在 Postgres 上,因此系统里看不到常驻的任务队列守护进程,排障和扩容都直白得多。架构全貌可参考 docs/architecture.md。

从原始职位到搜索结果:一条职位的完整路径

抓到一条职位只是开始,它还要经历三步才能出现在搜索结果里:

阶段机制关键实现
去重以(source, external_id)为唯一键 upsert,重复抓取零成本jobs表唯一约束
事务出站队列新职位写入同一事务中投递到enrichment_outbox/search_outbox事务性 outbox
批量索引进 Meilisearchcmd/search-drain/ 把整批文档作为单个任务推入索引批量合并,避免打满磁盘 IO

上图是 freehire 的职位搜索主页,左侧可按地区、工作形式、技术栈、资历等维度筛选——这些筛选维度的数据正来自上文各层数据源的归一化字段。

一个值得注意的工程细节:Meilisearch 每次推送都会对全量约 270 万条文档重建倒排索引(实测 90~180 秒),所以早期"每个看板进程各自直推"的设计曾打满宿主磁盘 IO,现在统一由出站队列把大量小推送合并成少量大批次——这也是为什么"未变化的重复抓取"只刷新时间戳、不触发重索引。

数字从哪来:快照保证全站口径一致

文章开头的 330 万、29.4 万这些数字,并不是各个页面各自实时估算的——那会导致"关于页"和"开放 API"说的数对不上。freehire 的做法是:

  • catalogstats(internal/ingest/catalogstats/catalogstats.go):定时 worker 精确统计一次全库快照(在招职位数、公司数、平台数),随后全站所有引用目录规模的页面都读同一个Snapshot,口径天然一致。
  • sourcestats(internal/ingest/sourcestats/sourcestats.go):把每天的"按来源分组"测量折叠成source_stats快照行,驱动每个数据源的公开统计页。

统计还刻意区分了"测量失败"和"测量结果为零"两种状态,避免公开页面把一个仍在运行的来源错误地显示为 0 条职位——这种细节决定了用户看到的数据是否可信。

版图还在长大:新增一家公司只需一行数据

freehire 的数据版图并非静态,它靠社区持续生长,而扩容成本被刻意压到最低:

  • 加一家已在支持平台上的公司=boards目录里加一行(company + provider + board)。可以直接在网站的 "contribute a board" 表单提交,或用go run ./cmd/add-board命令(实现见 cmd/add-board/main.go),新行首次爬取成功后自动转正。
  • 加一个全新的 ATS 平台= 在 internal/ingest/sources/ 写一个适配器 + 注册表加一行,工作量是有界的,因为所有适配器说同一种"语言"(Source接口)。
  • 下线一个看板= 把该行状态翻成retired,永不删除——爬虫只爬活行,误操作随时可逆。

快速上手:按这个顺序读项目资料

想了解的内容去哪里看
项目全貌与数据分层README.md
每个数据源的详细计数docs/sources.md
系统架构与数据流docs/architecture.md
数据源适配器源码internal/ingest/sources/
抓取流水线internal/ingest/pipeline/
看板目录(数据源清单)internal/ingest/boardcatalog/

上图演示了用 "Remote + Global/Worldwide" 组合筛选远程职位的效果——这类跨来源的联合筛选,正是 225 个数据源归一化的直接收益。

一句话总结:freehire 的数据版图 = 三层来源结构(ATS 平台为主力)+ 一次一平台的单程工抓取 + 事务化出站队列索引 + 统一快照统计。理解了这四件事,你就理解了这 330 万条职位是如何被"搭"起来的,以及它为什么还能持续长大。

【免费下载链接】freehire

freehire — the open-source search engine for job seekers

项目地址:https://gitcode.com/gh_mirrors/fr/freehire
点击查看免费下载

相关推荐

上一篇:多语言PDF对比工具:使用PolyglotPDF进行原文与译文对照
下一篇:情侣专属微信小程序:把恋爱玩成双人游戏,任务攒积分让感情天天升温

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 2:40:00

imakit 9.13:IM安卓开发中的ROM备份与调试工具箱

简介:IM安卓开发工具箱imakit 9.13更新包面向Android ROM开发者、刷机爱好者及系统定制人员,聚焦刷机包制作、系统img镜像备份与格式转换等核心场景。压缩包共283个文件,约18.26MB,以C与头文件、Python脚本及pyd扩展、exe可执行程…

作者头像 李华
网站建设 2026/10/20 2:39:55

微调模型接进 Open WebUI 效果就翻车?vLLM 部署一致性排错全记录

微调模型接进 Open WebUI 效果就翻车?vLLM 部署一致性排错全记录 【免费下载链接】open-webui User-friendly AI Interface (Supports Ollama, OpenAI API, ...) 项目地址: https://gitcode.com/GitHub_Trending/op/open-webui 把微调好的模型从训练脚本搬到…

作者头像 李华
网站建设 2026/10/20 2:38:52

卷积神经网络原理与图像分类项目实践:从卷积层到模型训练全解析

接触计算机视觉这一年多,把CNN从“会调接口”到“能讲明白原理”,期间踩了不少坑,也积累了一套比较稳的实践套路。最近正好带几个朋友从零复现一个图像分类项目,整个流程走下来,发现多数人对卷积神经网络的理解飘在半空…

作者头像 李华
网站建设 2026/10/20 2:36:40

网络安全方向怎么选?五大专业科研与高薪路线全拆解

总有人私信问我:网络安全方向到底怎么选?一搜全是“网络安全五大专业”,但翻遍帖子也没人把话说透——哪些方向适合沉下心搞科研,哪些方向能进大厂拿高薪。今天我不讲虚的,把这五个方向从学什么、产出什么、对应岗位、…

作者头像 李华