关于 Career Site Job Feed
Career Site Job Feed 是一组从企业招聘平台获取职位数据的脚本,面向需要汇总或跟踪招聘信息的开发者。它将不同平台的数据整理为统一字段,并提供 CSV 导出、职位变化对比和薪资整理示例。
主要功能
- 01覆盖 12 个招聘平台
- 02统一职位数据字段
- 03检测职位新增与关闭
- 04筛选并年化薪资范围
- 05将新职位追加到 CSV
适用场景
- 01跟踪企业职位的开放与关闭
- 02导出自上次运行以来的新职位
- 03汇总招聘信息中的薪资范围
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://mcp.apify.com/?tools=starbright_overlap/ats-job-feedclaude mcp add --transport http hwangbyeongseon-career-site-job-feed https://mcp.apify.com/?tools=starbright_overlap/ats-job-feed{"mcpServers":{"hwangbyeongseon-career-site-job-feed":{"type":"http","url":"https://mcp.apify.com/?tools=starbright_overlap/ats-job-feed"}}}在 Cursor 中打开{"servers":{"hwangbyeongseon-career-site-job-feed":{"type":"http","url":"https://mcp.apify.com/?tools=starbright_overlap/ats-job-feed"}}}在 VS Code 中打开{"mcpServers":{"hwangbyeongseon-career-site-job-feed":{"type":"http","url":"https://mcp.apify.com/?tools=starbright_overlap/ats-job-feed"}}}{"mcpServers":{"hwangbyeongseon-career-site-job-feed":{"serverUrl":"https://mcp.apify.com/?tools=starbright_overlap/ats-job-feed"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
https://mcp.apify.com/?tools=starbright_overlap/ats-job-feed需要授权工具
详细介绍
ATS 职位信息流实用示例
可直接运行的代码,用于从公司的申请人跟踪系统中直接获取招聘信息—— 包括 Greenhouse、Lever、Workday、Ashby、Workable、SmartRecruiters、Breezy、Personio、Recruitee、 BambooHR、Pinpoint 和 Rippling,并用这些信息完成实用任务。
各 ATS API 能提供哪些信息 — 涵盖所有 12 个平台的薪资、职位发布日期和远程办公标记,数据来自对 1,549,353 条有效招聘信息的统计。没有其他地方发布这些数据,因此,如果你正在选择要基于哪个平台构建,就从这里开始。
这里的每个脚本都能直接运行。设置 APIFY_TOKEN 即可。
export APIFY_TOKEN=... # https://console.apify.com/settings/integrations
python python/new_jobs_to_csv.py
存在的原因
这些平台都会发布一个开放的 JSON 端点,供公司自己的招聘页面读取—— 无需密钥或登录,也不用抓取渲染后的 HTML。棘手的部分在于其他所有事情:
- 每个平台的数据结构都不同。 Greenhouse 会嵌套办公地点和部门;Workday 使用
POST 请求,并将职位发布时间写成字符串
"Posted 30+ Days Ago";SmartRecruiters 无论你传入 什么limit,每次响应最多都只有 100 条;Breezy 对不存在的职位页面返回403,而其他平台都使用404。 - 查明哪些公司使用哪些平台,才是真正的工作。 没有公开的 Greenhouse 或 Personio 职位页面目录。职位页面的 slug 藏在某处的招聘页面 URL 里,前提是你能找到招聘页面的 URL。
- 日期并不可靠。 这 10 个平台中有 3 个完全不提供职位发布日期,因此任何“最近 N 天内发布”的筛选器都必须决定如何处理职位发布时间未知的记录。
下面的脚本使用了已经处理好所有这些问题的 Apify Actors,并在所有平台上返回统一的数据行结构。你也可以直接调用原始端点——文末的说明列出了这些端点。
实用示例
| 文件 | 功能 |
|---|---|
javascript/watch-companies.mjs | 比较每次运行时的公司职位清单差异——哪些职位已发布,哪些职位已关闭 |
javascript/salary-data.mjs | 发布了薪资范围的职位,并将薪资标准化为年薪 |
python/one_company.py | 根据公司的招聘页面 URL,获取该公司的所有开放职位 |
python/new_jobs_to_csv.py | 仅获取上次运行后出现的职位,并追加到 CSV 文件 |
这些 Actor 按交付的行数计费。每个脚本都会将行数限制在几百条,并读取 MAX_ROWS,以便你按需获取更多数据,因此运行示例不会产生意外费用。
数据行结构
无论职位来自哪个平台,每个实用示例都会获得相同的字段:
{
"provider": "greenhouse",
"company": "Databricks",
"companySlug": "databricks",
"jobId": "7845321",
"title": "Staff Software Engineer",
"location": "San Francisco, CA",
"department": "Engineering",
"employmentType": "Full-time",
"remote": false,
"postedAt": "2026-08-14T09:12:00.000Z",
"applyUrl": "https://boards.greenhouse.io/databricks/jobs/7845321",
"salary": null,
"descriptionText": "...",
"scrapedAt": "2026-08-19T11:02:41.883Z"
}
职位开放期间,companySlug:jobId 保持稳定,这正是职位差异比较示例能够正常工作的原因。
各平台实际发布的内容
数据来自实时职位看板,而非供应商文档。在基于其中任何一个平台构建之前,这些信息很有用:
相同的表格以及各列背后的说明,见完整参考页面。
| 平台 | 发布日期 | 职位描述 | 薪酬 | 标记为远程 |
|---|---|---|---|---|
| Workday | 78.2% | 无 | 无 | 无 |
| SmartRecruiters | 有 | 无 | 无 | 7.7% |
| Greenhouse | 有 | 有 | 无 | 无 |
| Workable | 有 | 有 | 无 | 36.3% |
| BambooHR | 无 | 无 | 无 | 无 |
| Lever | 有 | 94.7% | 无 | 4.8% |
| Breezy HR | 有 | 无 | 45.7% | 15.7% |
| Personio | 无 | 无 | 无 | 8.8% |
| Ashby | 有 | 有 | 38.9% | 54.2% |
| Recruitee | 有 | 有 | 26.9% | 9.9% |
| Rippling | 无 | 无 | 无 | 17.4% |
| Pinpoint | 无 | 有 | 42.5% | 8.8% |
每个平台的每一行都会返回 title、company、location 和 applyUrl。
这些是实测数据,不是功能矩阵。 每一行涵盖了本项目跟踪的该平台所有实时职位看板——每个平台有 17,000 至 179,000 条职位信息,测量日期为 2026-08-20。yes 表示 99.5% 或以上;no 表示接口完全不包含此类字段。
这张表说明了三件事:
- 四个平台会发布薪酬信息,但没有一个平台能在大多数职位中填入该信息。 Breezy 和 Pinpoint 的比例最高,分别为 45.7% 和 42.5%。Breezy 和 Ashby 提供文本描述(“$28 – $100 / hour”、“$211.4K – $290.6K • Offers Equity”);Pinpoint 和 Recruitee 则分别提供最低值、最高值、货币单位和周期。如果你要进行基准比较,请使用后两者。
- 半数平台不提供发布日期。 Personio、Rippling、Pinpoint 和 BambooHR 均不发布发布日期;Workday 只有 78.2% 的职位带有日期,因为它提供的是“Posted 30+ Days Ago”这类文本,而不是时间戳。任何时效性筛选器都必须决定是丢弃没有日期的职位,还是保留它们;诚实的默认做法是保留。
- 五个平台有真正的“远程”字段,其余平台只能靠猜。 Ashby 将 54.2% 的职位标记为远程,这更多反映了使用 Ashby 的用户群体,而非就业市场本身。平台没有此类字段时,唯一的办法就是匹配地点字符串,但这样会漏掉“Anywhere”,也会误判“Remote Support Engineer, London office”。
原始端点
如果你更愿意直接调用各平台,可以使用以下公开端点。它们都无需密钥即可响应。将 {company} 替换为职位板的标识。
| 平台 | 端点 |
|---|---|
| Greenhouse | https://boards-api.greenhouse.io/v1/boards/{company}/jobs?content=true |
| Lever | https://api.lever.co/v0/postings/{company}?mode=json |
| Ashby | https://api.ashbyhq.com/posting-api/job-board/{company}?includeCompensation=true |
| SmartRecruiters | https://api.smartrecruiters.com/v1/companies/{company}/postings?limit=100&offset=0 |
| Workable | https://apply.workable.com/api/v1/widget/accounts/{company}?details=true |
| Breezy | https://{company}.breezy.hr/json |
| Personio | https://{company}.jobs.personio.de/search.json |
| Pinpoint | https://{company}.pinpointhq.com/postings.json |
| Recruitee | https://{company}.recruitee.com/api/offers/ |
| BambooHR | https://{company}.bamboohr.com/careers/list |
| Rippling | https://api.rippling.com/platform/api/ats/v1/board/{company}/jobs |
| Workday | POST https://{tenant}.{cluster}.myworkdayjobs.com/wday/cxs/{tenant}/{site}/jobs |
如果你要编写自己的客户端,以下 4 点可能会让你踩坑:
- SmartRecruiters 每次响应最多返回 100 条职位信息,不受
limit影响。请使用offset翻页,并从totalFound获取实际总数,而不是统计行数。 - Recruitee 在雇主未填写薪资字段时,仍会保留薪资对象,但值为零,因此简单的读取器会将
"0 USD hour"作为薪资范围输出。请将min <= 0 && max <= 0视为缺失。 - BambooHR 将其招聘 API 拆分成了两部分。
/careers/list不包含职位发布日期、描述或薪酬信息;这些信息位于/careers/{id}/detail,需要为每个职位单独请求。此外,它的isRemote字段虽然存在,却从未填充——在测量的 50,616 条职位信息中,没有一条设置了该字段。 - Breezy 对于没有职位板的子域名会返回
403,而不是404。如果将其视为限流并进行退避,一个半小时的任务就会变成 14 小时。
许可证
MIT。此处调用的 Actors 是商业服务,按行收费;此处的代码不是。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。