
API 是你的程式向另一項服務發出的請求。Apify 是啟動工作並儲存結果的託管服務。Actor 是一個託管的數據收集程式。Naukri Jobs Actor 就是此方法中的 Actor。它讀取公開的 Naukri 頁面。它不使用 Naukri 登入。Task 是已儲存的輸入預設。目前的公開 Task 只是起始輸入。它不會為你分析職位。Actor 儲存來源列。你核對執行紀錄,並為你的專案選擇列。
此路徑使用 Apify 的 API。它不是官方 Naukri API。它不是私人公司資料庫。它不是印度職位的完整索引。它展示的是這一個公開 Actor。
1. 設定一次搜尋和列數上限
開始之前,先寫下你想要的列。選擇一個職位。選擇一個印度城市,或把城市留空。選擇來源刊登應有多新。選擇一個較小的已儲存列數上限。
目前的公開 Actor 接受以下輸入:
- `searchTerm` 每一行接受一個關鍵字。
- `location` 可選。
- `maxItems` 是列數上限。它限制整次執行所儲存的列。這個上限不是每個關鍵字行各自計算。如果你省略它,數字上限便不存在。此方法一定要傳送一個數字。
- `postedWithinDays` 是文字。使用 "0"、"1"、"3"、"7"、"15" 或 "30"。文字 "0" 表示任何刊登日期。
- `experienceYears` 可選。它是 0 至 30 的整數。Fresher 指該搜尋設定中先前工作經驗很少或沒有。數值 0 要求 Fresher 搜尋設定。此方法不判斷是否適合該職位。
- `sortBy` 是 `relevance` 或 `date`。
- `excludeCompanies` 可選。下面的例子不使用它。
- `searchDepth` 是 `standard`、`extended` 或 `deep`。`standard` 是範圍較窄的第一次檢查。它讀取的來源頁少於另外兩項。此方法不需要更深的搜尋。
目前的公開 Task 儲存 `searchTerm` "software engineer"、`postedWithinDays` "7"、`sortBy` "date" 和 `searchDepth` "standard"。把你的職位放進 `searchTerm`。如果你只要一個城市,把城市放進 `location`。設定你自己的 `maxItems`。
一次已核對的對照測試使用了不同的值。它使用一個關鍵字 "software engineer"。它沒有傳送地點。它使用 `postedWithinDays` "0"、`maxItems` 2、`sortBy` "relevance" 和 `searchDepth` "standard"。該次執行儲存了兩個互不相同的 Naukri 職位 ID。每一列都有職稱、公司名稱和地點。每一列都有直接的 Naukri `jobUrl`。每個 `sourceUrl` 都符合所請求的查詢。`source` 是 naukri.com。每一列都有 `observedAt`。兩列都包含 `descriptionText`。兩列都包含 `experienceRaw`。兩個數字範圍是 0-5 和 0-2。這些 0 是觀察到的最低年數。它們不是空白欄位。該對照測試沒有傳送 `experienceYears`。它不能證明已套用 Fresher 篩選。
該次已核對的執行以成功結束。它的 OUTPUT 紀錄顯示這些已知值。`rowsSaved` 是 2。`requestedMaxItems` 是 2。`pagesRequested` 是 1。執行紀錄報告已見到 20 個候選。`failedRequests` 是 0。`blockedRequests` 是 0。`stopReason` 是 `max_items_reached`。該次執行達到上限。兩列已儲存的資料不是每一個符合的職位。該對照測試沒有寫明 `searchesQueued`、`searchesFinished` 或 `sourceStates`。這三個值未知。未知不等於 0。
已儲存的列可以包含下列欄位。
- `schemaVersion`
- `jobId`
- `title`
- `companyName`
- `location`
- `experienceRaw`
- `experienceMinYears`
- `experienceMaxYears`
- `skills`
- `descriptionText`
- `postedAt`
- `postedAtRaw`
- `jobUrl`
- `searchTerm`
- `searchLocation`
- `sourceUrl`
- `pageNumber`
- `rankOnPage`
- `status`
- `statusReason`
- `source`
- `observedAt`
可選的值可以不存在。不存在就是未知。它不是 0。`descriptionText` 可以存在,但仍缺少部分僱主文字。它也可以缺少一項要求。`postedAt` 和經驗欄位是來源所顯示的內容。它們不是僱主將會聘用的承諾。`observedAt` 是 Actor 見到該列的時間。它不是 Naukri 首次刊登該職位的時間。把這兩個時間分開保留。
`searchTerm`、`searchLocation` 和 `observedAt` 屬於原始來源列。如果你日後加入自己的 query 欄,那個欄是你建立的。它不是名為 query 的來源欄位。
2. 啟動執行並保留執行 ID
使用你自己的 Apify 帳戶。把令牌放在你的專案已經用來存放秘密的安全位置。令牌是一項秘密,證明該呼叫屬於你的帳戶。不要把真實令牌放進文章。不要放進瀏覽器程式碼。不要放進日誌。不要放進一張含有網址的圖片。這次公開讀取不需要 Naukri 登入。
啟動呼叫傳回關於該次執行的資訊。它不傳回職位列。一次執行是 Actor 的一次啟動。以 JSON 傳送輸入。JSON 是用於結構化數據的文字格式。加入標頭 `Content-Type: application/json`。在 `Authorization` 標頭傳送令牌。寫下 `Bearer`、一個空格,然後是令牌。下面的內容是原創教學輸入。它不是即時結果。
POST https://api.apify.com/v2/acts/chronometrica~naukri-jobs-scraper/runs
Authorization: Bearer <APIFY_TOKEN>
Content-Type: application/json
{
"searchTerm": "data analyst",
"location": "Bengaluru",
"maxItems": 2,
"postedWithinDays": "7",
"sortBy": "date",
"searchDepth": "standard"
}此內容要求的職位是數據分析師。它把地點限制為 Bengaluru。它最多儲存 2 列。它要求最近 7 日的刊登。它按日期排序。它使用 standard 深度。啟動執行的說明文件 描述此端點。同一個 API 讓你可以設定逾時和費用上限。費用上限會在你選擇的成本限制停止該次執行。第一次執行時,兩個限制都要設定。本文不提供價格。
從回應中儲存 `data.id`。那就是執行 ID。同時儲存該服務所儲存的輸入和選項。執行 ID、資料集 ID 和儲存 ID 是三個不同的值。保持它們互不混淆。
3. 等待終結狀態
用同一個私密標頭讀取該次執行。每次讀取之間等待一段短時間。狀態成為終結狀態時便停止。終結狀態是已結束的狀態。已結束的值是 `SUCCEEDED`、`FAILED`、`TIMED-OUT` 和 `ABORTED`。
GET https://api.apify.com/v2/actor-runs/<RUN_ID>
Authorization: Bearer <APIFY_TOKEN>儲存 `status`、`buildId`、`startedAt`、`finishedAt`、`defaultDatasetId` 和 `defaultKeyValueStoreId`。`SUCCEEDED` 表示 Actor 已完成。它不表示來源已被完整覆蓋。`FAILED`、`TIMED-OUT` 和 `ABORTED` 在你信任這些列之前需要查看。執行狀態說明文件 描述這次讀取。
4. 讀取 OUTPUT 執行紀錄
OUTPUT 是 Actor 的摘要紀錄。從鍵值儲存讀取它。鍵值儲存為該次執行保存具名紀錄。使用 `defaultKeyValueStoreId` 作為儲存 ID。
GET https://api.apify.com/v2/key-value-stores/<STORE_ID>/records/OUTPUT
Authorization: Bearer <APIFY_TOKEN>讀取這些欄位:
- `rowsSaved` 是已儲存的列數。
- `requestedMaxItems` 是你要求的上限。
- `searchesQueued` 是已排入隊列的搜尋工作。
- `searchesFinished` 是已完成的搜尋工作。
- `pagesRequested` 是所請求的來源頁數。來源頁是一個 Naukri 結果頁。它不是對已儲存資料集的一次讀取。
- `blockedRequests` 是被封鎖的來源請求數目。
- `failedRequests` 是失敗的來源請求數目。
- `sourceStates` 說明來源如何結束。
- `stopReason` 說明 Actor 為何停止。
如果 `rowsSaved` 等於 `requestedMaxItems`,而且 `stopReason` 是 `max_items_reached`,上限已停止該次執行。這些列仍然可以有用。它們不是完整搜尋。一個被點算為 0 的值表示 Actor 報告沒有。缺少的欄位是未知。不要把未知改成 0。
在你解釋一個空檔案之前,先使用 `sourceStates`。空結果可以表示來源沒有傳回任何列。也可以表示未能到達來源。這兩個結果不同。如果 `failedRequests` 或 `blockedRequests` 高於 0,不要把該城市當成沒有資料。如果缺少 `sourceStates`,來源結果便是未知。無論哪一種情況,都保留執行紀錄。
5. 在執行結束後讀取資料集
資料集是已儲存的列項目集合。在執行成為終結狀態之後才讀取它。仍在增長的資料集並不穩定。先完成該次執行。如果你需要在結束前取得列,要有意地設計那種情況。不要把中間的一頁當成最終集合。
GET https://api.apify.com/v2/datasets/<DATASET_ID>/items?format=json&offset=0&limit=2
Authorization: Bearer <APIFY_TOKEN>回應是一個 JSON 陣列。`offset` 是要跳過的已儲存列數。`limit` 是這次讀取要傳回的列數。這次讀取是資料集的一頁。它不是 Naukri 來源頁。資料集項目說明文件 描述此呼叫。點算陣列中的列數。把該數目加到 `offset`。再讀取一次。為每一次讀取保留一份小執行紀錄。該紀錄需要 offset、limit、傳回數目,以及任何讀取錯誤。
對於一個已完成、有兩列的資料集,第一次讀取可以傳回兩列。下一次讀取使用 offset 2 和 limit 2。它可以傳回一個空陣列。空陣列的傳回數目是 0。那個 0 表示此頁沒有更多列。它不表示較早的列已消失。已讀列數是 2。如果 `rowsSaved` 是 2,這些數目相符。
如果一次資料集讀取失敗,把該失敗保留在執行紀錄中。不要用空陣列取代失敗的讀取。尚未讀取的列仍然未知。
6. 篩選之前先儲存身分
儲存原始列。把 `jobId` 儲存為文字。保留前導零。如果程式把 ID 儲存為數字,可能會去掉這些零。在職位 ID 前加入來源前綴 `naukri:`。該前綴是命名空間。命名空間顯示哪個網站建立了該 ID。另一個職位網站可以用相同數字表示不同職位。它的命名空間保持分開。
同時儲存 `jobUrl`、`sourceUrl`、原始 `searchTerm`、原始 `searchLocation`、`observedAt` 和執行 ID。檢查身分是否存在。檢查你預期的類型。如果缺少 `jobId`,該列保持未能對應。未能對應表示你尚未能把該列連到一個來源職位。不要為它建立來源鍵。
一次觀察是對一個來源列的一次已儲存所見紀錄。同一刊登在較後的執行中,是對一個已知來源職位的新觀察。它不會自動成為一個新的在招職位。保持重複列可見。保持同一個身分的兩列之間的衝突可見。然後套用你的專案規則。當你選出有用的列時,把失敗的列保留在執行紀錄中。
薪酬的含義不在此方法之內。關於是否適合職位的規則不在此方法之內。此方法不提交申請。日後的排程是另一個選擇。本文不啟動重複收集。
7. 整理一份已完成的執行紀錄
本節的故事是原創虛構。它不是即時測試輸出。它不是產品結果。ID、網址和時間是為教學而編造的。不要請求這些故事網址。不要把這些列當成真實的 Naukri 列。
虛構執行 R1 使用啟動一節的教學內容。故事中的請求是一個 POST,送往 `https://api.apify.com/v2/acts/chronometrica~naukri-jobs-scraper/runs` ,並附上 `Content-Type: application/json`。故事的啟動回應包含 `data.id` "R1"。它不包含職位列。
R1 其後以狀態 `SUCCEEDED` 結束。故事的資料集 ID 是 D1。故事的儲存 ID 是 K1。故事中已儲存的執行紀錄如下:
{
"data": {
"id": "R1",
"status": "SUCCEEDED",
"buildId": "fiction-build",
"startedAt": "2026-04-01T09:00:00Z",
"finishedAt": "2026-04-01T09:05:00Z",
"defaultDatasetId": "D1",
"defaultKeyValueStoreId": "K1"
}
}故事的 OUTPUT 紀錄是:
{
"rowsSaved": 2,
"requestedMaxItems": 2,
"failedRequests": 0,
"stopReason": "max_items_reached"
}在這個故事中,該 OUTPUT 紀錄沒有給出 `blockedRequests`、`searchesQueued`、`searchesFinished`、`pagesRequested` 和 `sourceStates`。讓它們保持未知。不要為它們寫下 0。`failedRequests` 是 0,因為故事說明沒有失敗的請求。那個 0 是已知的。
第一次資料集讀取使用 offset 0 和 limit 2。它傳回這個陣列:
[
{
"jobId": "000101",
"jobUrl": "https://www.naukri.com/example-fiction/000101",
"sourceUrl": "https://www.naukri.com/example-fiction/search",
"searchTerm": "data analyst",
"searchLocation": "Bengaluru",
"source": "naukri.com",
"observedAt": "2026-04-01T09:04:00Z"
},
{
"jobId": "000102",
"jobUrl": "https://www.naukri.com/example-fiction/000102",
"sourceUrl": "https://www.naukri.com/example-fiction/search",
"searchTerm": "data analyst",
"searchLocation": "Bengaluru",
"source": "naukri.com",
"observedAt": "2026-04-01T09:04:00Z"
}
]傳回數目是 2。這些故事列不包含 `postedAt`。刊登時間未知。它不是 0。下一次讀取使用 offset 2 和 limit 2。它傳回:
[]傳回數目是 0。已讀列數是 2。`rowsSaved` 是 2。數目相符:2 等於 2。已知來源 ID 是 `naukri:000101` 和 `naukri:000102`。那是兩個已知 ID。前導零保留在文字中。兩列都保留故事的來源網址、原始查詢欄位和 `observedAt`。上限表示兩個被觀察到的刊登。它不表示 Bengaluru 只有兩個在招職位。
同一虛構的後段是執行 R2。故事說 R2 再次傳回 `000102`,並傳回 `000103`。它沒有給出另外一份 OUTPUT 紀錄。不要為 R2 編造 `stopReason` 或請求數目。它的兩列故事資料是:
[
{
"jobId": "000102",
"jobUrl": "https://www.naukri.com/example-fiction/000102",
"sourceUrl": "https://www.naukri.com/example-fiction/search",
"searchTerm": "data analyst",
"searchLocation": "Bengaluru",
"source": "naukri.com",
"observedAt": "2026-04-08T09:04:00Z"
},
{
"jobId": "000103",
"jobUrl": "https://www.naukri.com/example-fiction/000103",
"sourceUrl": "https://www.naukri.com/example-fiction/search",
"searchTerm": "data analyst",
"searchLocation": "Bengaluru",
"source": "naukri.com",
"observedAt": "2026-04-08T09:04:00Z"
}
]把兩列 R2 都儲存為新的觀察。只有 `naukri:000103` 是新的已知來源 ID。`naukri:000102` 已經已知。
算術使用普通計數:
- R1 觀察 = 2。
- R2 觀察 = 2。
- 全部觀察 = 2 + 2 = 4。
- R1 之後的已知 ID = 2。
- R2 上的新已知 ID = 1。
- R2 上重複的已知 ID = 1。
- 兩次執行之後的已知 ID = 2 + 1 = 3。
- 這四列中未能對應的 ID = 0,因為每一列故事資料都有 `jobId`。
四次觀察不是四個職位。三個已知來源 ID 不是三個僱主職位。故事沒有僱主之間的獨立配對。它不能證明有三個空缺。
| 檢查 | 數目 |
|---|---|
| R1 觀察 | 2 |
| R2 觀察 | 2 |
| 全部觀察 | 4 |
| 已知來源 ID | 3 |
| R2 中的新已知 ID | 1 |
| R2 中重複的已知 ID | 1 |
| 四列中未能對應的 ID | 0 |
| 已證明的僱主職位 | 未顯示 |
還有一次額外的虛構檢查,它不屬於那四列。如果一次下載在同一頁重複 `000102`,記錄該重複。不要建立第二個身分。已知 ID 仍然是 `naukri:000102`。如果另一列故事資料有職稱但沒有 `jobId`,把未能對應加 1。不要建立例如 `naukri:unknown` 的鍵。
把原始列、執行 ID 和這份執行紀錄交給你的專案。加上簡短說明:這些列來自公開 Naukri 頁面,並經由此 Actor 取得。加上 `observedAt` 中的時間。然後專案便可以使用這個樣本。上限不是完整市場。
來源與延伸閱讀
作者 Chronometrica · 更新日期
返回頂端 ↑
