# JobKorea Job Scraper — Korean Jobs, Salaries & Hiring Companies (`youfuxu/jobkorea-korea-jobs-scraper`) Actor

Scrape job postings from JobKorea (jobkorea.co.kr), Korea's biggest job board. Titles, companies, regions, salary ranges in KRW, experience and education requirements, employment type, deadlines, benefits and full descriptions as clean JSON.

- **URL**: https://apify.com/youfuxu/jobkorea-korea-jobs-scraper.md
- **Developed by:** [Youfu Xu](https://apify.com/youfuxu) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## JobKorea Job Scraper — Korean jobs, salary ranges & hiring companies

Get clean, structured job data from **[JobKorea](https://www.jobkorea.co.kr)** (잡코리아) — Korea's largest job board with millions of monthly users and tens of thousands of live postings from Samsung suppliers to Pangyo startups. Search any keyword in Korean or English, optionally narrow by region, experience level and employment type, and download the results as JSON, CSV or Excel. No login, no browser, no proxy setup.

### What you get

Run it with the default input and results look like this:

```json
{
  "url": "https://www.jobkorea.co.kr/Recruit/GI_Read/49664866",
  "jobId": "49664866",
  "title": "케이엠아이시스템(주) - SW 개발자 (C# / Python 능숙자) 경력사원 채용",
  "companyName": "케이엠아이시스템㈜",
  "companyUrl": "https://www.jobkorea.co.kr/Company/1758150",
  "companyLogoUrl": "https://imgs.jobkorea.co.kr/Images/Logo/128/k/m/2290V00VYDA4886_2620U7bUW48532VU.gif?p=y&hash=c",
  "location": "경기 성남시 중원구",
  "locationCodes": ["B170"],
  "industry": "전기·전자·제어",
  "jobRoles": ["전기·전자엔지니어"],
  "careerType": "Experienced",
  "careerText": "경력5년↑",
  "minExperienceYears": 5,
  "education": "Associate degree or above",
  "educationText": "초대졸↑",
  "employmentType": "Full-time (permanent)",
  "employmentTypeText": "정규직",
  "salaryText": "연봉 4,800만원~",
  "salaryMin": 48000000,
  "salaryMax": null,
  "salaryCurrency": "KRW",
  "salaryPeriod": "year",
  "benefits": ["4대보험", "퇴직연금", "자유로운 연차 사용", "기숙사 지원", "점심 식사 지원", "유연근무"],
  "skills": ["개발", "소프트웨어", "유지보수", "개발설계", "하드웨어개발"],
  "tools": ["autocad", "cad", "c#", "python", "파이썬"],
  "applyMethod": "Apply on JobKorea",
  "postedAt": "2026-07-28T09:26:11.857+09:00",
  "applicationStart": "2026-07-28T00:00:00+09:00",
  "deadline": "2026-08-27T23:00:00+09:00",
  "viewCount": 1103,
  "isEntryLevelFriendly": false,
  "badges": ["VIEWS_OVER_1000", "FLEXIBLE_WORK"],
  "scrapedAt": "2026-08-21T02:26:26.314Z"
}
```

**33 fields per posting by default** — straight from the search results, no detail pages needed: title, company with profile link and logo, region (시/도 + 구/시), industry and job roles, experience level with minimum years, education requirement, employment type(s), the salary range JobKorea publishes converted to plain KRW numbers, benefits, skill and tool keywords, application method, posting date, deadline and view count. Korean labels are kept in `*Text` fields next to English normalised values, so the data works for both Korean and international teams.

Turn on **Include detail page data** and each posting also gets the **full job description text**, the street address with latitude / longitude, the exact salary as entered by the employer, probation or contract length, working hours, headcount, every application channel with the external apply URL (Greeting, Recruiter.co.kr, company career sites) and the HR contact the employer chose to expose — **58 fields** in total.

### Who uses this

- **Recruiters & sourcing agencies** — see which Korean companies are hiring for which roles, in which city, at what pay, before your competitors do
- **Salary benchmarking & HR analytics** — `salaryMin` / `salaryMax` / `salaryPeriod` are already numbers in KRW, so 연봉 3,000~3,300만원 becomes `30000000 – 33000000 / year` with no parsing
- **B2B lead generation** — every row carries the hiring company, its JobKorea profile, logo, district and (in detail mode) the exposed HR email / phone
- **Job aggregators & alert bots** — sort by *Newest first*, run hourly, diff against the last dataset by `jobId`
- **Labour-market & investment research** — count open roles for AI, semiconductor, battery or bio skills across Korea by region over time
- **Job seekers relocating to Korea** — filter by region and experience level and export to a spreadsheet

### How to use

1. Enter a **keyword** — `python`, `데이터 분석`, `마케팅`, `반도체 공정`, `nurse`… JobKorea matches titles, skills and company names
2. Optionally set a **region** — English or Korean names (`Seoul`, `경기`, `Busan, Incheon`) or JobKorea area codes (`I000` Seoul, `B000` Gyeonggi, `I010` Seoul › Gangnam-gu). Comma-separate several regions
3. Optionally pick an **experience level** (entry / experienced / no requirement) and an **employment type** (full-time, contract, internship, freelance, part-time…)
4. Pick a **sort order** — *Newest first* is best for monitoring, *Closing soonest* for urgent sourcing
5. Set **Max jobs** (default 50; JobKorea pages 20 at a time, up to 5,000 per run)
6. Optionally enable **Include detail page data** for descriptions, addresses, apply URLs and HR contacts
7. Run, then download from the **Dataset** tab as JSON / CSV / Excel, or pull it through the Apify API

#### Example input

```json
{
  "keyword": "데이터 엔지니어",
  "location": "Seoul, Gyeonggi",
  "careerType": "2",
  "employmentType": "1",
  "sortBy": "RegDtDesc",
  "maxItems": 300,
  "includeDetails": true
}
```

### Output fields

| Field | Description |
| --- | --- |
| `url` | Link to the posting on JobKorea |
| `jobId` | JobKorea posting ID (stable — use it to de-duplicate between runs) |
| `title` | Posting title |
| `companyName`, `companyUrl`, `companyLogoUrl` | Hiring company, its JobKorea profile and logo |
| `location`, `locationCodes` | Work region as shown on JobKorea (e.g. `서울 강남구`, `경기 용인시 외 13`) and the raw area codes |
| `industry`, `jobRoles` | Industry and the job-role tags JobKorea assigned |
| `careerType`, `careerText`, `minExperienceYears` | Entry level / Experienced / Any, the Korean label (`경력5년↑`) and the minimum years |
| `education`, `educationText` | Minimum education in English and Korean |
| `employmentType`, `employmentTypeText` | Full-time, contract, internship, freelance, part-time… in English and Korean |
| `salaryText` | Salary exactly as JobKorea displays it (`연봉 4,800만원~`, `월급 500~550만원`, `시급 10,320원~`) |
| `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod` | Numeric KRW range and period (`year`, `month`, `week`, `day`, `hour`, `case`). Empty when the employer lists pay as "company policy" |
| `benefits` | Benefit tags (4대보험, 퇴직연금, 유연근무…) |
| `skills`, `tools` | Skill and tool keywords JobKorea extracted from the posting |
| `applyMethod` | Apply on JobKorea / Company website / Email / … |
| `postedAt`, `applicationStart`, `deadline` | ISO timestamps in Korea Standard Time |
| `viewCount`, `badges`, `isEntryLevelFriendly` | Popularity and posting badges |
| `scrapedAt` | When the row was collected |
| **Detail mode only** | |
| `description` | Full job description as plain text |
| `summary` | JobKorea's one-line summary of the posting |
| `address`, `latitude`, `longitude` | Workplace street address and coordinates |
| `salaryType`, `experienceYearsMin`, `experienceYearsMax` | Pay type enum and experience range exactly as the employer entered them |
| `employmentDetails` | Employment type with probation / contract length |
| `workWeek`, `workHours`, `vacancy`, `workFields`, `alwaysHiring`, `closesOnHire` | Working conditions and headcount |
| `applyChannels`, `applyUrl` | All application channels and the external apply link when the company hires through its own site |
| `hrContactName`, `hrContactDepartment`, `hrContactEmail`, `hrContactPhone` | HR contact, only the parts the employer chose to expose publicly |
| `datePosted`, `validThrough`, `experienceRequirement`, `educationRequirement` | Schema.org JobPosting metadata from the detail page |

### Limitations

- Around 15–25 % of postings publish a salary range; the rest say "회사 내규에 따름" (company policy) and come back with an empty `salaryText`. Detail mode occasionally recovers an exact figure the list hides.
- Some employers upload their posting as an image. For those, `description` only contains the text JobKorea renders around the image.
- JobKorea caps search results at 500 pages (10,000 postings) per query. Use a narrower keyword or a region filter for bigger exports.
- Detail mode makes two extra requests per posting (the job page and the description document) and paces itself at about one posting per 1.5 seconds.

### Legal

This Actor collects only publicly available job postings for research, recruiting and analytics purposes. Respect JobKorea's terms of service and Korean personal-data law when you use contact details.

# Actor input Schema

## `keyword` (type: `string`):

What to search for, e.g. <code>python</code>, <code>데이터 분석</code>, <code>마케팅</code>, <code>반도체</code>. Korean or English both work — JobKorea matches titles, skills and company names.

## `location` (type: `string`):

Optional. One or more regions separated by commas — English or Korean names (<code>Seoul</code>, <code>경기</code>, <code>Busan, Incheon</code>) or JobKorea area codes (<code>I000</code> Seoul, <code>B000</code> Gyeonggi, <code>I010</code> Seoul › Gangnam-gu). Leave empty for all of Korea.

## `careerType` (type: `string`):

Optional. Limit to entry-level (신입), experienced (경력) or postings open to any experience level (경력무관).

## `employmentType` (type: `string`):

Optional. Limit to one employment type.

## `sortBy` (type: `string`):

How JobKorea orders the results before the scraper walks through them. Use <b>Newest first</b> for daily monitoring.

## `maxItems` (type: `integer`):

Maximum number of postings to return (JobKorea pages 20 at a time). Keep it small for a quick test, raise it for a full export.

## `includeDetails` (type: `boolean`):

Visit each posting to add the full job description text, street address with coordinates, exact salary as posted, working hours, application channels / external apply URL, headcount and the exposed HR contact. Two extra requests per posting, so it is noticeably slower — the search results already include title, company, region, salary range, experience, education, employment type, benefits, skills and deadline without it.

## Actor input object example

```json
{
  "keyword": "python",
  "location": "",
  "careerType": "",
  "employmentType": "",
  "sortBy": "RelevanceDesc",
  "maxItems": 50,
  "includeDetails": false
}
```

# Actor output Schema

## `datasetItemsJson` (type: `string`):

All scraped records as a JSON array.

## `datasetItemsCsv` (type: `string`):

All scraped records as a CSV file.

## `datasetItemsXlsx` (type: `string`):

All scraped records as an Excel workbook.

## `dataset` (type: `string`):

The default dataset of this run in Apify Console.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "keyword": "python",
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("youfuxu/jobkorea-korea-jobs-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "keyword": "python",
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("youfuxu/jobkorea-korea-jobs-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "keyword": "python",
  "maxItems": 50
}' |
apify call youfuxu/jobkorea-korea-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,youfuxu/jobkorea-korea-jobs-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/5ZcYqKXkUk8Rzd7NR/builds/9Q4NLLfavmXhbjXt5/openapi.json
