78 套應徵者追蹤系統,統一架構
freehire 的承諾刻意保持樸實無華:每一筆職缺,統一成單一格式,去除重複,並連結回公司自己的招募頁面。樸實正是重點所在。不那麼光鮮的是,「單一格式」背後隱藏著一長串幾乎對如何讀取毫無共識的應徵者追蹤系統。
截至本週,目錄已從 78 個 ATS 平台抓取資料——合計 290 萬筆開放下來的職缺。這是整合如此多平台帶給我們的啟示,我們不以廠商分類,而是依照每個平台帶來的問題類型來分組。
整潔型平台
少數幾個平台讓資料彙整真的變得乏味——是好的那種乏味。Lever(api.lever.co/v0/postings)、Ashby(api.ashbyhq.com/posting-api/job-board)、
Greenhouse、SmartRecruiters:每個看板都有公開、有文件的 JSON 端點,合理的分頁,穩定的欄位名稱。你只要把轉接器指向一家公司的看板權杖就完成了。freehire 中大多數長尾的公司資料——每家一行 YAML——都靠這四個平台運作,因為當平台已經能輸出乾淨的 JSON,新增一家公司根本微不足道。
如果你是求職平台,正在決定要打造什麼:這就是門檻。一個樸實、穩定的 JSON 資料來源,是對你所有下游使用者最體貼的一件事。
重量級平台
以數量來看,前五大平台說明了這個故事:Workday(831,217 筆開放下來的職缺)、 Oracle(291,963)、SmartRecruiters(257,443)、Greenhouse(178,084)與 iCIMS (122,532)。光是 Workday 就佔了全部的四分之一。在這樣的規模下,那些怪癖不再是奇聞軼事,而是正確性問題:一個分頁端點若在暫時性錯誤時回報總數為零,你若盲目信任它,就會在一次錯誤的執行中「關閉」數萬筆仍在招募中的職缺。規模會迫使你把來源提供的每個數字視為待驗證的說法,而非事實。
串流型平台
有些平台根本不提供分頁的 API——它們一次就把全部資料丟給你。nofluffjobs 把它的職缺列表以單一份約 60 MB 的文件回應; 幾個 isolved 的租戶則將其完整的職缺 sitemap 以單一串流傳送。你無法把這些資料緩衝到記憶體後再解析;轉接器必須在位元組抵達時就進行串流解碼。這是個很好的提醒——「API」有時候就只是「一個非常大的檔案」,而你的讀取器從一開始就必須為此而打造。
有狀態型平台
接著是一些平台,你必須先取得憑證才能發出第一個有用的請求。Cornerstone 在招募頁面嵌入一個帶有短效 JWT 讀取權杖的 JSON 設定區塊;你必須先抓取該權杖,再以 Bearer 方式送到真正的搜尋端點。Taleo 則要求你先建立工作階段並設定正確的時區,才願意與你通訊。這些都沒有任何說明文件——你只能觀察瀏覽器的行為來推測交握方式,然後加以重現。
水合型平台
最後這群平台,說實話根本沒有 API。職缺資料藏在頁面內——嵌入式 JSON、JSON-LD,或是框架的伺服器端算繪水合酬載(Next.js 的 flight 資料、SSR 資料孤島)。所謂的「整合」其實就是萃取:找出結構化資料藏在 HTML 何處,在它變成像素之前把它取出來。
結論
單一架構值得付出這個代價。從外部來看,freehire 像是一個帶有分面篩選器的單一資料來源;但骨子裡,這 78 個平台中的每一個,都各自需要對同樣的三個問題給出自己的答案——如何列出、如何分頁、如何讀取單一筆職缺。價值不在於任何單一轉接器,而是在於:一旦職缺通過了這條管線,所有下游——搜尋、去重、API、還有你——都不必在意它來自這些世界中的哪一個。
整條管線以及完整的逐來源拆解都是開源的; README 中的 Sources 表格 列出每個平台及其當前數量。如果這類東西對你有幫助——或者你只是喜歡直接來自來源的職缺——在 GitHub 上留下一個 ⭐,能幫助其他人找到它。